【问题标题】:Matlab neural network handwritten digit recognition, output going to indifferenceMatlab神经网络手写数字识别,输出无差异
【发布时间】:2019-11-30 10:59:23
【问题描述】:

我正在尝试使用 Matlab 构建一个可以对 30x30 像素的手写数字进行分类的神经网络。我使用反向传播来找到正确的权重和偏差。该网络以 900 个输入开始,然后有 2 个隐藏层和 16 个神经元,并以 10 个输出结束。每个输出神经元都有一个介于 0 和 1 之间的值,表示输入应该被分类为某个数字的信念。问题在于,经过训练后,输出对输入几乎无动于衷,并且每个输出都趋向于 0.1 的统一信念。

我的方法是获取每个 30x30 像素的图像并将其重塑为 900x1 的矢量(请注意,“Images_vector”在加载时已经是矢量格式)。权重和偏差以 0 到 1 之间的随机值启动。我使用随机梯度下降来更新权重和偏差,每批随机选择 10 个样本。方程式如Nielsen 所述。

脚本如下。

%% Inputs
numberofbatches = 1000;
batchsize = 10;
alpha = 1;
cutoff = 8000;
layers = [900 16 16 10];

%% Initialization
rng(0);

load('Images_vector')
Images_vector = reshape(Images_vector', 1, 10000);
labels = [ones(1,1000) 2*ones(1,1000) 3*ones(1,1000) 4*ones(1,1000) 5*ones(1,1000) 6*ones(1,1000) 7*ones(1,1000) 8*ones(1,1000) 9*ones(1,1000) 10*ones(1,1000)];
newOrder = randperm(10000);
Images_vector = Images_vector(newOrder);
labels = labels(newOrder);
images_training = Images_vector(1:cutoff);
images_testing = Images_vector(cutoff + 1:10000);

w = cell(1,length(layers) - 1);
b = cell(1,length(layers));
dCdw = cell(1,length(layers) - 1);
dCdb = cell(1,length(layers));
for i = 1:length(layers) - 1
    w{i} = rand(layers(i+1),layers(i));
    b{i+1} = rand(layers(i+1),1);
end

%% Learning process
batches = randi([1 cutoff - batchsize],1,numberofbatches);

cost = zeros(numberofbatches,1);
c = 1;
for batch = batches
    for i = 1:length(layers) - 1
        dCdw{i} = zeros(layers(i+1),layers(i));
        dCdb{i+1} = zeros(layers(i+1),1);
    end

    for n = batch:batch+batchsize
        y = zeros(10,1);
        disp(labels(n))
        y(labels(n)) = 1;

        % Network
        a{1} = images_training{n};
        z{2} = w{1} * a{1} + b{2};
        a{2} = sigmoid(0, z{2});
        z{3} = w{2} * a{2} + b{3};
        a{3} = sigmoid(0, z{3});
        z{4} = w{3} * a{3} + b{4};
        a{4} = sigmoid(0, z{4});

        % Cost
        cost(c) = sum((a{4} - y).^2) / 2;

        % Gradient
        d{4} = (a{4} - y) .* sigmoid(1, z{4});
        d{3} = (w{3}' * d{4}) .* sigmoid(1, z{3});
        d{2} = (w{2}' * d{3}) .* sigmoid(1, z{2});

        dCdb{4} = dCdb{4} + d{4} / 10;
        dCdb{3} = dCdb{3} + d{3} / 10;
        dCdb{2} = dCdb{2} + d{2} / 10;

        dCdw{3} = dCdw{3} + (a{3} * d{4}')' / 10;
        dCdw{2} = dCdw{2} + (a{2} * d{3}')' / 10;
        dCdw{1} = dCdw{1} + (a{1} * d{2}')' / 10;

        c = c + 1;
    end

    % Adjustment
    b{4} = b{4} - dCdb{4} * alpha;
    b{3} = b{3} - dCdb{3} * alpha;
    b{2} = b{2} - dCdb{2} * alpha;
    w{3} = w{3} - dCdw{3} * alpha;
    w{2} = w{2} - dCdw{2} * alpha;
    w{1} = w{1} - dCdw{1} * alpha;
end

figure
plot(cost)
ylabel 'Cost'
xlabel 'Batches trained on'

sigmoid 函数如下。

function y = sigmoid(derivative, x)

if derivative == 0
    y = 1 ./ (1 + exp(-x));
else
    y = sigmoid(0, x) .* (1 - sigmoid(0, x));
end

end

除此之外,我还尝试在每批中的每个数字中有 1 个,但这给出了相同的结果。我也尝试过改变批次大小、批次数和 alpha,但没有成功。

有谁知道我做错了什么?

【问题讨论】:

    标签: matlab neural-network mnist


    【解决方案1】:

    如果我错了,请纠正我:您的数据中有 10000 个样本,您将其分为 1000 个批次,每批 10 个样本。您的训练过程包括对这 10000 个样本运行一次。

    这可能太少了,通常您的训练过程包含几个 epoch(一个 epoch = 迭代每个样本一次)。您可以尝试多次检查批次。

    此外,对于 900 个输入,您的网络似乎很小。尝试在第二层使用更多神经元。希望对您有所帮助!

    【讨论】:

    • 你是对的,我创建了 1000 个批次,但这些批次有一个随机的起始索引。两个示例批次可以是 10-20 和 15-25,其中 10 和 15 是随机选择的。我会尝试使用几个时期,谢谢你的提示!关于大小,我认为它应该没问题,因为它适用于3Blue1Brown 提供的示例。
    • 不幸的是,即使有 100 个 epoch,也没有任何改进。
    猜你喜欢
    • 1970-01-01
    • 2017-11-20
    • 2011-12-12
    • 2011-09-18
    • 1970-01-01
    • 2015-10-11
    • 2018-08-29
    • 2012-05-29
    • 2015-04-29
    相关资源
    最近更新 更多