使用飞桨搭一个简单的神经网络
前言
应该是昨天吧,使用numpy搭了一个简单的神经网络(传送直通车——使用numpy搭一个简单的神经网络),那么今天就来一个使用飞桨(paddlepaddle)来搭一个吧。
毕竟国产的要支持一下,不然以后美国再一出手,不允许google对中国开源tensorflow,不允许facebook对中国开源pytorch,难不成我们又要回到解放前?还是老老实实学学国产的吧。
详细思路
不外乎还是那样,只是不需要你们手动去写梯度相关:
处理数据
跟上一篇一样,不详细说了。
def load_data():
global minimums, maximums, averages
file_path = './work/housing.data'
data = np.fromfile(file_path, sep=' ')
feature_size = 14
data = data.reshape((data.shape[0]) // feature_size, feature_size)
train_test_index = int(0.8 * data.shape[0])
train_data = data[:train_test_index, :]
test_data = data[train_test_index:, :]
minimums, maximums, averages = train_data.min(axis=0), train_data.max(axis=0), train_data.mean(axis=0)
for i in range(feature_size):
data[:, i] = (data[:, i] - averages[i]) / (maximums[i] - minimums[i])
train_data = data[:train_test_index, :]
test_data = data[train_test_index:, :]
return train_data, test_data
写出前向过程
在这里写出前向过程,是继承了fluid.dygraph.Layer,在初始化里定义你需要的模型,这里可以有多种层,说不定以后会用到的卷积层,全连接层。然后复写它的forward方法,在里面进行前向传播。
class Network(fluid.dygraph.Layer):
def __init__(self):
super(Network, self).__init__()
self.fc = fluid.dygraph.Linear(input_dim=13, output_dim=1, act=None)
def forward(self, x):
z = self.fc(x)
return z
选择优化器
飞桨提供了多种优化器,毕然老师说的,使用的优化器两只手都可以数出来,不够的话,再加上两只脚(后面的是我加的)。
opt = fluid.optimizer.SGD(0.01, parameter_list=model.parameters())
训练过程
对于训练过程,这里在讲一下:
打乱数据、小批量化
这一点本来不想说,不过还是提一句吧。
np.random.shuffle(train_data)
mini_batchs = [train_data[k:k+10] for k in range(0, n, 10)]
转成tensor
在之前的numpy神经网络里没有这一步,现在是使用fluid.dygraph.to_variable来转换。
x = np.array(mini_batch[:, :-1]).astype(np.float32) # np.float32才OK
y = np.array(mini_batch[:, -1:]).astype(np.float32) # np.float32才OK
house_features = fluid.dygraph.to_variable(x)
price = fluid.dygraph.to_variable(y)
前向计算
刚刚我们已经建立了网络,用这个网络来call一下。
# model = Network()
# model.train() # 该神经网络设置为训练模式。
# 前面已经定义过了这里只是告诉你们读者,不要问这个model是哪里来的。
pred = model(house_features)
计算损失并反向传播
上一次的计算损失是要自己写
M
S
E
MSE
MSE的公式,现在只要使用fluid.layers.square_error_cost就可以了。
loss = fluid.layers.square_error_cost(pred, price)
avg_loss = fluid.layers.mean(loss)
avg_loss.backward()
使用优化器最小化损失
这里帮你更新找最小的损失时的权重和偏置。
opt.minimize(avg_loss)
清理梯度??Dish还不太明白
这一点我不知道如果解释,反正用不用这个都是一样的可以训练出来。知情的大神请赐教一下吧。
model.clear_gradients() # 可有可无
保存模型
主要是保存model.state_dict()。那么你记住,取出的时候也是model.state_dict()。
fluid.save_dygraph(model.state_dict(), 'Dish_LR')
验证、使用模型
load模型
这里包括了“使用相同网络结构”,“从文件中load模型”,“网络结构加载模型”。fluid.load_dygraph返回值是两个值的,如果一不小心就会得到一个元组,下一步load_dict就会出错。注意这里将网络设置为推理模式。
model = Network() # 要相同的结构
model_dict, _ = fluid.load_dygraph('./Dish_LR')
model.load_dict(model_dict)
model.eval() # 该神经网络设置为推理模式。
转换为tensor并开始推理
飞桨的预测,是直接用神经网络对象做为函数去调用,它里面是调用__call__方法
test_x = fluid.dygraph.to_variable(test_x)
test_ret = model(test_x)
全部代码
import numpy as np
import matplotlib.pyplot as plt
from paddle import fluid
def load_data():
global minimums, maximums, averages
file_path = './work/housing.data'
data = np.fromfile(file_path, sep=' ')
feature_size = 14
data = data.reshape((data.shape[0]) // feature_size, feature_size)
train_test_index = int(0.8 * data.shape[0])
train_data = data[:train_test_index, :]
test_data = data[train_test_index:, :]
minimums, maximums, averages = train_data.min(axis=0), train_data.max(axis=0), train_data.mean(axis=0)
for i in range(feature_size):
data[:, i] = (data[:, i] - averages[i]) / (maximums[i] - minimums[i])
train_data = data[:train_test_index, :]
test_data = data[train_test_index:, :]
return train_data, test_data
class Network(fluid.dygraph.Layer):
def __init__(self, ):
super(Network, self).__init__()
self.fc = fluid.dygraph.Linear(input_dim=13, output_dim=1, act=None)
def forward(self, x):
z = self.fc(x)
return z
with fluid.dygraph.guard():
model = Network()
model.train() # 该神经网络设置为训练模式。
train_data, test_data = load_data()
opt = fluid.optimizer.SGD(0.01, parameter_list=model.parameters())
# print(model.parameters())
with fluid.dygraph.guard(fluid.CPUPlace()):
n = train_data.shape[0]
losses = []
for epoch_i in range(500):
np.random.shuffle(train_data)
mini_batchs = [train_data[k:k+10] for k in range(0, n, 10)]
for iten_i, mini_batch in enumerate(mini_batchs):
# x = np.array(mini_batch[:, :-1]).astype(np.float32)
# y = np.array(mini_batch[:, -1:]).astype(np.float32)
x = np.array(mini_batch[:, :-1]).astype(np.float32) # np.float32才OK
y = np.array(mini_batch[:, -1:]).astype(np.float32) # np.float32才OK
house_features = fluid.dygraph.to_variable(x)
price = fluid.dygraph.to_variable(y)
pred = model(house_features)
loss = fluid.layers.square_error_cost(pred, price)
avg_loss = fluid.layers.mean(loss)
avg_loss.backward()
opt.minimize(avg_loss)
model.clear_gradients() # 可有可无
losses.append(avg_loss.numpy()[0])
if epoch_i % 100 == 0:
print('epoch {}, loss {}'.format(epoch_i, avg_loss.numpy()))
fluid.save_dygraph(model.state_dict(), 'Dish_LR')
plt.plot(losses)
plt.show()
with fluid.dygraph.guard():
model = Network() # 要相同的结构
model_dict, _ = fluid.load_dygraph('./Dish_LR')
model.load_dict(model_dict)
model.eval() # 该神经网络设置为推理模式。
test_data = np.array(test_data).astype(np.float32)
test_x = test_data[:, :-1]
test_y = test_data[:, -1:]
test_x = fluid.dygraph.to_variable(test_x)
test_ret = model(test_x)
test_ret = test_ret * (maximums[-1] - minimums[-1]) + averages[-1]
test_y = test_y * (maximums[-1] - minimums[-1]) + averages[-1]
print('pred {}: true {}'.format(str(test_ret.numpy()), str(test_y)))

本文介绍使用飞桨(paddlepaddle)搭建神经网络的方法。详细阐述了处理数据、写出前向过程、选择优化器等思路,还说明了训练过程,包括打乱数据、转成tensor、前向计算等步骤,最后提及验证和使用模型的方法,并给出全部代码。
2217

被折叠的 条评论
为什么被折叠?



