基于matlab实现数字识别的代码
时间: 2023-12-10 22:06:07 浏览: 82
以下是基于MATLAB实现数字识别的代码:
1. 加载训练数据和测试数据
```matlab
load('mnist_train.mat');
load('mnist_test.mat');
```
2. 数据预处理
```matlab
% 转换成二维数组
X_train = reshape(X_train, [28*28, 60000])';
X_test = reshape(X_test, [28*28, 10000])';
% 标准化
mean_train = mean(X_train);
std_train = std(X_train);
X_train = (X_train - mean_train) ./ std_train;
X_test = (X_test - mean_train) ./ std_train;
% 转换为分类问题
Y_train = zeros(size(X_train, 1), 10);
for i = 1:size(X_train, 1)
Y_train(i, y_train(i)+1) = 1;
end
```
3. 训练模型
```matlab
input_size = 28*28;
hidden_size = 25;
output_size = 10;
W1 = randn(input_size, hidden_size) * 0.01;
b1 = zeros(1, hidden_size);
W2 = randn(hidden_size, output_size) * 0.01;
b2 = zeros(1, output_size);
num_epochs = 100;
learning_rate = 0.1;
batch_size = 100;
for epoch = 1:num_epochs
% 随机打乱数据
shuffle_index = randperm(size(X_train, 1));
X_train = X_train(shuffle_index, :);
Y_train = Y_train(shuffle_index, :);
% 分批处理
for batch_start = 1:batch_size:size(X_train, 1)
batch_end = min(batch_start+batch_size-1, size(X_train, 1));
X_batch = X_train(batch_start:batch_end, :);
Y_batch = Y_train(batch_start:batch_end, :);
% 前向传播
Z1 = X_batch * W1 + b1;
A1 = sigmoid(Z1);
Z2 = A1 * W2 + b2;
A2 = softmax(Z2);
% 计算损失和梯度
loss = -sum(sum(Y_batch .* log(A2))) / size(X_batch, 1);
dZ2 = A2 - Y_batch;
dW2 = A1' * dZ2 / size(X_batch, 1);
db2 = sum(dZ2, 1) / size(X_batch, 1);
dZ1 = (dZ2 * W2') .* sigmoid_gradient(Z1);
dW1 = X_batch' * dZ1 / size(X_batch, 1);
db1 = sum(dZ1, 1) / size(X_batch, 1);
% 更新参数
W1 = W1 - learning_rate * dW1;
b1 = b1 - learning_rate * db1;
W2 = W2 - learning_rate * dW2;
b2 = b2 - learning_rate * db2;
end
% 输出每个epoch的损失
fprintf('Epoch %d, Loss: %f\n', epoch, loss);
end
```
4. 测试模型
```matlab
% 前向传播
Z1 = X_test * W1 + b1;
A1 = sigmoid(Z1);
Z2 = A1 * W2 + b2;
A2 = softmax(Z2);
% 计算准确率
[~, predict_test] = max(A2, [], 2);
accuracy = sum(predict_test-1 == y_test) / size(X_test, 1);
fprintf('Test Accuracy: %f\n', accuracy);
```
完整代码如下:
```matlab
load('mnist_train.mat');
load('mnist_test.mat');
% 转换成二维数组
X_train = reshape(X_train, [28*28, 60000])';
X_test = reshape(X_test, [28*28, 10000])';
% 标准化
mean_train = mean(X_train);
std_train = std(X_train);
X_train = (X_train - mean_train) ./ std_train;
X_test = (X_test - mean_train) ./ std_train;
% 转换为分类问题
Y_train = zeros(size(X_train, 1), 10);
for i = 1:size(X_train, 1)
Y_train(i, y_train(i)+1) = 1;
end
input_size = 28*28;
hidden_size = 25;
output_size = 10;
W1 = randn(input_size, hidden_size) * 0.01;
b1 = zeros(1, hidden_size);
W2 = randn(hidden_size, output_size) * 0.01;
b2 = zeros(1, output_size);
num_epochs = 100;
learning_rate = 0.1;
batch_size = 100;
for epoch = 1:num_epochs
% 随机打乱数据
shuffle_index = randperm(size(X_train, 1));
X_train = X_train(shuffle_index, :);
Y_train = Y_train(shuffle_index, :);
% 分批处理
for batch_start = 1:batch_size:size(X_train, 1)
batch_end = min(batch_start+batch_size-1, size(X_train, 1));
X_batch = X_train(batch_start:batch_end, :);
Y_batch = Y_train(batch_start:batch_end, :);
% 前向传播
Z1 = X_batch * W1 + b1;
A1 = sigmoid(Z1);
Z2 = A1 * W2 + b2;
A2 = softmax(Z2);
% 计算损失和梯度
loss = -sum(sum(Y_batch .* log(A2))) / size(X_batch, 1);
dZ2 = A2 - Y_batch;
dW2 = A1' * dZ2 / size(X_batch, 1);
db2 = sum(dZ2, 1) / size(X_batch, 1);
dZ1 = (dZ2 * W2') .* sigmoid_gradient(Z1);
dW1 = X_batch' * dZ1 / size(X_batch, 1);
db1 = sum(dZ1, 1) / size(X_batch, 1);
% 更新参数
W1 = W1 - learning_rate * dW1;
b1 = b1 - learning_rate * db1;
W2 = W2 - learning_rate * dW2;
b2 = b2 - learning_rate * db2;
end
% 输出每个epoch的损失
fprintf('Epoch %d, Loss: %f\n', epoch, loss);
end
% 前向传播
Z1 = X_test * W1 + b1;
A1 = sigmoid(Z1);
Z2 = A1 * W2 + b2;
A2 = softmax(Z2);
% 计算准确率
[~, predict_test] = max(A2, [], 2);
accuracy = sum(predict_test-1 == y_test) / size(X_test, 1);
fprintf('Test Accuracy: %f\n', accuracy);
function y = sigmoid(x)
y = 1 ./ (1 + exp(-x));
end
function y = sigmoid_gradient(x)
y = sigmoid(x) .* (1 - sigmoid(x));
end
function y = softmax(x)
x = exp(x - max(x, [], 2));
y = x ./ sum(x, 2);
end
```
阅读全文