一,说明
1)有以下几个文件:
BP_Net.m--用于网络训练;
BPTest.m--用于测试;
net_value.m--用于求输出值;
sigmod_func.m--定义激活函数;
test_func.m--逼近的函数;

2)实验说明
1、本实现隐藏层采用tanh作为激活函数,输出层线性函数为激活函数;
2、逼近函数为sin(x) + cos(x);
3、由于逼近函数值为1附近,所以没有进行归一化处理;

二、程序
% BP神经网络
% x:样本输入,y为样本输出,hide_node_arry为神经网络隐藏层神经元个数
% w:权重 b:偏置项

function [w, b] = BP_Net(x, y, hide_node_array)
    eps = 1e-10;


% 神经元节点个数

[xnum, xlen] = size(x);
    [~, ylen] = size(y);
    node_array = [xlen, hide_node_array, ylen];



% 初始化权重和偏置项

[w, b] = init_w_b(node_array);

    L = length(node_array) - 1;

    d_error = 1;
    maxItorNum = 100000000;
    num = 0;
    while abs(d_error) > eps



% 遍历样本

sum_error = 0;
        for i = 1: xnum

% 计算网络中的输入和输出值

[layer_in, layer_out] = net_value(w, b, x(i, :));

% 计算各层神经元误差

d = layer_out{L + 1};
            error = calc_error(d, y(i), w, b, layer_in);
            sum_error = sum_error + error{L};

% 更新权重w和偏置项b

[w, b] = adjust_w_b(error, w, b, layer_out);

        end

        d_error = sum_error / xnum;

        fprintf('Iteration number = %d;   d_error = %d\n', num, d_error);
        num = num + 1;

        if mod(num, 100) == 0
            plotf(w, b, num);
        end

        if num > maxItorNum
            fprintf('d_error = %d\n', d_error);
            break;
        end

    end

end

% 计算各层神经元误差

function error = calc_error(d, y, w, b, layer_in)

% 神经元层数(不包括输入层)

L = length(b);
    error = cell(1, L);



% 计算输出层误差(输出层采用线性函数)

error{L} = (d-y);



% 计算2~L-1层误差

for i = 1: L-1
        layer = L - i;
        error{layer} = calc_error_2(error{layer+1}, w{layer+1}, layer_in{layer});
    end

end

% 计算所有神经元节点误差(2~L-1层)

function delta = calc_error_2(back_error, back_w, layer_in)

    diff_f = @sigmod_diff_func;

    node_num = length(layer_in);
    back_node_num = length(back_error);
    delta = zeros(node_num, 1);
    for i = 1: node_num   
        for j = 1: back_node_num
            delta(i) =  delta(i) + back_error(j)*back_w(j, i)*diff_f(layer_in(i));
        end
    end

end

% 调整权重w和偏置项b,从前往后调节

function [w, b] = adjust_w_b(delta, w, b, layer_out)
    alpha = 0.005;   % 步长
    L = length(b);

    for i = 1: L
        w{i} = adjust_w(w{i}, delta{i}, layer_out{i}, alpha);
        b{i} = adjust_b(b{i}, delta{i}, alpha);
    end

end

% 调整权重w

function w = adjust_w(w, delta, pre_layer_out, alpha)

node_num = length(delta); % 该层神经元节点个数和误差个数一样
input_node_num = length(pre_layer_out); % 前一层神经元节点个数
% 调整每个神经元节点对应的权重

for i = 1: node_num
        for j = 1: input_node_num
            w(i, j) = w(i, j) - alpha.*delta(i).*pre_layer_out(j);
        end
    end

end

% 调整偏置项

function b = adjust_b(b, delta, alpha)
    node_num = length(delta);   % 该层神经元节点个数和误差个数一样
    for i = 1: node_num
        b(i) = b(i) - alpha.*delta(i);
    end
end

% 初始化权重和偏置项

function [w, b] = init_w_b(node_array)
    layer = length(node_array);
    w = cell(1, layer-1);
    b = cell(1, layer-1);
    for i = 2: layer
          input_node_num = node_array(i-1);
          node_num = node_array(i);
          w{i-1} = rands(node_num, input_node_num);
          b{i-1} = rands(node_num);
    end
end

% sigmod导数

function v = sigmod_diff_func(x)
    f = @sigmod_func;
    v = 1 - f(x)*f(x);
endfunction plotf(w, b, num)
    f = @test_func;
    x = linspace(-pi, pi, 50)';
    y = f(x);

    tx = -pi:0.01:pi;
    ty = tx;
    index = 1;
    for xi = tx
        [~,o] = net_value(w, b, xi);
        ty(index) = o{4};
        index = index + 1;
    end    hold on; cla reset;
    plot(x, y, '*r');
    hold on; 
    plot(tx, ty, '-g');
    legend('points on test_func', 'net fit line');
    title(['Iteration Num = ', num2str(num)]);

    pause(0.05);
end

% 计算网络值
% layer_in每一层输入值(不包括输入层),layer_out每一层输出值 x输入样本

function [layer_in, layer_out] = net_value(w, b, x)
    layer = length(b);
    layer_in = cell(1, layer);
    layer_out = cell(1, layer + 1);
    layer_out{1} = x';
    f = @sigmod_func;

    for i = 1: layer
        wl = w{i};
        bl = b{i};
        node_num = length(bl);
        input_node_num = length(layer_out{i});
        pre_in = layer_out{i};

        in = zeros(node_num, 1);
        for j = 1: node_num
            for k = 1: input_node_num
                in(j) = in(j) + wl(j, k)*pre_in(k);
            end
            in(j) = in(j) + bl(j);
        end

        layer_in{i} = in;

        if i == layer
            layer_out{i+1} = in;   % 输出层采用线性函数
        else
            layer_out{i+1} = f(in);
        end

    end

end% 获取sigmod值
function v = sigmod_func(x)
    v = (exp(x) - exp(-x))./(exp(x) + exp(-x));
end% 拟合的函数
function func = test_func(x)
    func = (sin(x) + cos(x))/1;
end% Test
clear;clc;close;
format long g;f = @test_func;
x = linspace(-pi, pi, 50)';
y = f(x);close all; figure;
[w, b] = BP_Net(x, y, [3,3]);

三、结果

matlab 神经网络 gpu matlab 神经网络函数_ide