前言
神经网络通常用于分类任务,也可以用于回归任务。使用一个含有隐层的神经网络可以很轻松地拟合出非线性曲线。下面是几个示例,包含matlab的和python的,都很简单。
实例1
首先,生成正弦曲线,并引入随机噪声。随后,在matlab中使用feedforwardnet函数创建BP神经网络,训练网络,并查看最后的拟合结果。
%%
clc;
clear all;
close all;
%% 生成正弦曲线
x = linspace(-2*pi, 2*pi, 100);
y = sin(x);
% 对目标值加入噪声
n = 0.1 * rand(1, length(x));
y = y + n;
% figure();
% plot(x, y, 'b-');
%% 数据归一化,创建测试数据集
[x_, ps] = mapminmax(x);
data_input = x_;
data_target = y;
% figure();
% plot(data_input, data_target, 'b-');
data_test = linspace(-5, 5, 50);
data_true = sin(data_test);
data_t = mapminmax('apply', data_test, ps);
% figure();
% plot(data_t, data_true, 'b-');
%% 创建神经网络(也可打开nntool,在matlab中使用gui创建神经网络)
hidden_layer_size = 10;
net = feedforwardnet(hidden_layer_size);
[net, tr] = train(net, data_input, data_target);
%% 拟合结果
data_y = sim(net, data_t);
% data_y = net(data_t);
figure();
e = 0.5 * (data_true - data_y) .^ 2;
plot(e);
xlabel('x axis');
ylabel('y axis');
legend('error');
figure();
hold on;
plot(data_test, data_y, '*');
plot(x, y, 'b');
xlabel('x axis');
ylabel('y axis');
legend('prediction', 'real value');
运行结果截图:
x轴是测试数据的x坐标,y轴是x坐标对应预测值和曲线真实值的误差。
曲线和拟合结果:
实例2
这里还是用matlab进行的实验。拟合的目标是一个圆,将圆拆成上下两条曲线,分别进行拟合。
%%
clc;
clear all;
close all;
%% 生成圆的上半边和下半边
center_x = 0;
center_y = 0;
radius = 4;
x1 = [];
x2 = [];
y1 = [];
y2 = [];
for theta = 0:0.1:pi
x_ = center_x + radius * cos(theta);
x1 = [x1 x_];
y_ = center_y + radius * sin(theta);
y1 = [y1 y_];
end
for theta = pi:0.1:2*pi
x_ = center_x + radius * cos(theta);
x2 = [x2 x_];
y_ = center_y + radius * sin(theta);
y2 = [y2 y_];
end
% 绘制曲线
figure();
hold on;
plot(x1, y1);
plot(x2, y2);
xlabel('x');
ylabel('y');
xlim([-(radius+2), (radius+2)]);
ylim([-(radius+2), (radius+2)]);
%% 创建神经网络
hidden_layer_size = 8;
net1 = feedforwardnet(hidden_layer_size);
net2 = feedforwardnet(hidden_layer_size);
[net1, tr] = train(net1, x1, y1);
[net2, tr] = train(net2, x2, y2);
%% 测试结果
test_x = linspace(-5, 5, 20);
p1 = sim(net1, test_x);
p2 = sim(net2, test_x);
% figure();
% hold on;
plot(test_x, p1, '*');
plot(test_x, p2, '*');
xlim([-(radius+2), (radius+2)]);
ylim([-(radius+2), (radius+2)]);
结果截图:
从结果来看,训练好的网络只在圆所在范围内预测有效,出了范围就失效了。
实例3
例子很简单,使用tensorflow构建了一个单隐层神经网络,并进行拟合。
首先导入模块。
import tensorflow as tf
import numpy as np
import matplotlib.pyplot as plt
创建数据,并引入噪声。
x_data = np.linspace(-1,1,300)[:, np.newaxis]
noise = np.random.normal(0, 0.05, x_data.shape)
y_data = np.square(x_data) - 0.5 + noise
绘制图片看看。
plt.plot(x_data, y_data)
创建TensorFlow的占位符,用于后面导入数据。
xs = tf.placeholder(tf.float32, [None, 1])
ys = tf.placeholder(tf.float32, [None, 1])
创建一个全连接层(隐藏层),激活函数为relu。
w1 = tf.Variable(tf.random_normal([1, 10]))
b1 = tf.Variable(tf.zeros([1, 10]) + 0.1)
ip1 = tf.matmul(xs, w1) + b1
out1 = tf.nn.relu(ip1)
输出层,不接激活函数。
w2 = tf.Variable(tf.random_normal([10,1]))
b2 = tf.Variable(tf.zeros([1, 1]) + 0.1)
ip2 = tf.matmul(out1, w2) + b2
out2 = ip2
loss为均方误差,使用SGD训练网络。
loss = tf.reduce_mean(tf.reduce_sum(tf.square(ys-out2), reduction_indices=[1]))
train_step = tf.train.GradientDescentOptimizer(0.1).minimize(loss)
初始化参数,创建会话。
init = tf.global_variables_initializer()
sess = tf.Session()
sess.run(init)
开始训练。
for i in range(1000):
_, loss_value = sess.run([train_step, loss], feed_dict={xs:x_data, ys:y_data})
if i%50==0:
print(loss_value)
0.914197
0.0143666
0.00786084
0.00659379
0.00575486
0.00504135
0.00450164
0.00415548
0.00389943
0.00368641
0.00353138
0.00337983
0.00325611
0.00315293
0.0030722
0.00300812
0.0029489
0.00290472
0.00286406
0.00282905
预测结果看看。
pred = sess.run(out2, feed_dict={xs:x_data})
可以看出拟合出了大致的曲线,但是受到噪声干扰不是很标准。
plt.plot(x_data, pred)