@1007477689
2020-03-29T18:35:51.000000Z
字数 7095
阅读 701
Python
import numpy as np
import matplotlib.pyplot as plt
import os
import pickle
import tensorflow as tf
tf.__version__
c = tf.zeros([3, 3])
tf.ones_like(c)
tf.fill([2, 3], 6)
# 2x3 全为 6 的常量 Tensor
tf.random.normal([3,3])
a = tf.constant([[1, 2], [3, 4]])
# 形状为 (2, 2) 的二维常量
a
a.numpy()
tf.linspace(1.0, 10.0, 5)
tf.range(start = 1, limit = 10, delta = 2)
a + a
tf.matmul(a, a)
tf.multiply(a, a)
tf.linalg.matrix_transpose(c)
b = tf.linspace(1.0, 10.0, 12)
# 方法一
tf.reshape(b, [3, 4])
# 方法二
tf.reshape(b, [3, -1])
这一部分将会实现 在 处的导数
x = tf.Variable([1.0])
x
with tf.GradientTape() as tape:
# 追踪梯度
y = x * x
grad = tape.gradient(y, x)
# 计算梯度
grad
这一部分将生成添加随机噪声的沿100个的数据点,再对这些数据点进行拟合。
X = tf.random.normal([100, 1]).numpy()
noise = tf.random.normal([100, 1]).numpy()
y = 3*X + 2 + noise
# 可视化这些点
plt.scatter(X, y)
W = tf.Variable(np.random.randn())
b = tf.Variable(np.random.randn())
print(f'W: {W.numpy()}, b: {b.numpy()})
def linear_regression(x):
return W * x + b
def mean_square(y_pred, y_true):
return tf.reduce_mean(tf.square(y_pred - y_true))
with tf.GradientTape() as tape:
pred = linear_regression(X)
loss = mean_square(pred, y)
dW, db = tape.gradient(loss, [W, b])
W.assign_sub(0.1*dW)
b.assign_sub(0.1*db)
print('W: %f, b: %f'%(W.numpy(), b.numpy()))
for i in range(20):
with tf.GradientTape() as tape:
pred = linear_regression(X)
loss = mean_square(pred, y)
dW, db = tape.gradient(loss, [W, b])
W.assign_sub(0.1 * dW)
b.assign_sub(0.1 * db)
print("step: %i, loss: %f, W: %f, b: %f" % (i+1, loss, W.numpy(), b.numpy()))
# 画出最终拟合的曲线
plt.plot(X, y, 'ro', label = 'Original data')
plt.plot(X, np.array(W * X + b), label = 'Fitted line')
plt.legend()
plt.show()
这部分将会在CIFAR10数据集上,训练LeNet5模型
模型结构如下所示:
CIFAR10数据集为32x32的3通道图像,标签共10个种类
输入图片:3×32×32
卷积核大小:5×5
卷积核种类:6
所以需要定义5×5×3×6个权重变量,和6个bias变量
conv1_w = tf.Variable(tf.random.truncated_normal([5,5,3,6], stddev=0.1))
conv1_b = tf.Variable(tf.zeros([6]))
输入:14×14×6
卷积核大小:5×5
卷积核种类:16
所以需要定义5×5×6×16个权重变量,和16个bias变量
conv2_w = tf.Variable(tf.random.truncated_normal([5, 5, 6, 16], stddev=0.1))
conv2_b = tf.Variable(tf.zeros([16]))
输入:5×5×16
输出:120
fc1_w = tf.Variable(tf.random.truncated_normal([5*5*16, 120], stddev=0.1))
fc1_b = tf.Variable(tf.zeros([120]))
输入:120
输出:84
fc2_w = tf.Variable(tf.random.truncated_normal([120, 84], stddev=0.1))
fc2_b = tf.Variable(tf.zeros([84]))
输入:84
输出:10
fc3_w = tf.Variable(tf.random.truncated_normal([84, 10], stddev=0.1))
fc3_b = tf.Variable(tf.zeros([10]))
def lenet5(input_img):
## 31.搭建INPUT->C1的步骤
conv1_1 = tf.nn.conv2d(input_img, conv1_w, strides=[1,1,1,1], padding="VALID")
conv1_2 = tf.nn.relu(tf.nn.bias_add(conv1_1,conv1_b))
## 32.搭建C1->S2的步骤
pool1 = tf.nn.max_pool(conv1_2,ksize=[1,2,2,1],strides=[1,2,2,1],padding="VALID")
## 33.搭建S2->C3的步骤
conv2_1 = tf.nn.conv2d(pool1,conv2_w,strides=[1,1,1,1],padding="VALID")
conv2_2 = tf.nn.relu(tf.nn.bias_add(conv2_1,conv2_b))
## 34.搭建C3->S4的步骤
pool2 = tf.nn.max_pool(conv2_2,ksize=[1,2,2,1],strides=[1,2,2,1],padding="VALID")
## 35.将S4的输出扁平化
reshaped = tf.reshape(pool2,[-1, 16*5*5])
## 35.搭建S4->C5的步骤
fc1 = tf.nn.relu(tf.matmul(reshaped,fc1_w) + fc1_b)
## 36.搭建C5->F6的步骤
fc2 = tf.nn.relu(tf.matmul(fc1,fc2_w) + fc2_b)
## 37.搭建F6->OUTPUT的步骤
OUTPUT = tf.nn.softmax(tf.matmul(fc2,fc3_w) + fc3_b)
return OUTPUT
optimizer = tf.optimizers.Adam(learning_rate=0.02)
验证网络正确性
(随便搞点数据,验证一下能不能跑通) ###39.随机一对x,y数据,x的形状为(1,32,32,3),y的形状为(10,)###
test_x = tf.Variable(tf.random.truncated_normal([1,32,32,3]))
test_y = [1,0,0,0,0,0,0,0,0,0]
将数据送入模型,进行反向传播
with tf.GradientTape() as tape:
## 40.将数据从入模型
prediction = lenet5(test_x)
print("第一次预测:", prediction)
## 41.使用交叉熵作为损失函数,计算损失
cross_entropy = -tf.reduce_sum(test_y * tf.math.log(prediction))
trainable_variables = [conv1_w, conv1_b, conv2_w, conv2_b, fc1_w, fc1_b, fc2_w, fc2_b, fc3_w, fc3_b] # 需优化参数列表
grads = tape.gradient(cross_entropy, trainable_variables)
optimizer.apply_gradients(zip(grads, trainable_variables))
print("反向传播后的预测:", lenet5(test_x))
读入数据,预处理
## load_cifar()定义略
train_X, train_Y, test_X, test_Y = load_cifar('/home/kesci/input/cifar10')
classes = ('plane', 'car', 'bird', 'cat',
'deer', 'dog', 'frog', 'horse', 'ship', 'truck')
train_X.shape, train_X.shape, test_X.shape, test_Y.shape
捞一个数据看看样子
plt.imshow(train_X[0])
plt.show()
print(classes[train_Y[0]])
train_X = tf.cast(train_X, dtype=tf.float32) / 255
test_X = tf.cast(test_X, dtype=tf.float32) / 255
45.预处理2:将train_y, test_y进行onehot编码
train_Y = tf.one_hot(train_Y, depth=10)
test_Y = tf.one_hot(test_Y, depth=10)
训练网络
因为前面实验的时候修改过参数,所以需要重新初始化所有参数
conv1_w = tf.Variable(tf.random.truncated_normal([5,5,3,6], stddev=0.1))
conv1_b = tf.Variable(tf.zeros([6]))
conv2_w = tf.Variable(tf.random.truncated_normal([5, 5, 6, 16], stddev=0.1))
conv2_b = tf.Variable(tf.zeros([16]))
fc1_w = tf.Variable(tf.random.truncated_normal([5*5*16, 120], stddev=0.1))
fc1_b = tf.Variable(tf.zeros([120]))
fc2_w = tf.Variable(tf.random.truncated_normal([120, 84], stddev=0.1))
fc2_b = tf.Variable(tf.zeros([84]))
fc3_w = tf.Variable(tf.random.truncated_normal([84, 10], stddev=0.1))
fc3_b = tf.Variable(tf.zeros([10]))
然后再重新定义一个优化器
optimizer2 = tf.optimizers.Adam(learning_rate=0.002)
简简单单随便写一个算准确率的函数
def accuracy_fn(y_pred, y_true):
preds = tf.argmax(y_pred, axis=1) # 取值最大的索引,正好对应字符标签
labels = tf.argmax(y_true, axis=1)
return tf.reduce_mean(tf.cast(tf.equal(preds, labels), tf.float32))
EPOCHS = 5 # 整个数据集迭代次数
for epoch in range(EPOCHS):
for i in range(25): # 一整个数据集分为10个小batch训练
with tf.GradientTape() as tape:
prediction = lenet5(train_X[i*2000:(i+1)*2000])
cross_entropy = -tf.reduce_sum(train_Y[i*2000:(i+1)*2000] * tf.math.log(prediction))
trainable_variables = [conv1_w, conv1_b, conv2_w, conv2_b, fc1_w, fc1_b, fc2_w, fc2_b, fc3_w, fc3_b] # 需优化参数列表
grads = tape.gradient(cross_entropy, trainable_variables) # 计算梯度
optimizer2.apply_gradients(zip(grads, trainable_variables)) # 更新梯度
# 每训练完一次,输出一下训练集的准确率
accuracy = accuracy_fn(lenet5(train_X), train_Y)
print('Epoch [{}/{}], Train loss: {:.3f}, Test accuracy: {:.3f}'
.format(epoch+1, EPOCHS, cross_entropy/2000, accuracy))
使用网络进行预测
test_prediction = lenet5(test_X)
test_acc = accuracy_fn(test_prediction, test_Y)
test_acc.numpy()
取一些数据查看预测结果
plt.figure(figsize=(10,10))
for i in range(25):
plt.subplot(5,5,i+1)
plt.imshow(test_X[i], cmap=plt.cm.binary)
title=classes[np.argmax(test_Y[i])]+'=>'
title+=classes[np.argmax(test_prediction[i])]
plt.xlabel(title)
plt.xticks([])
plt.yticks([])
plt.grid(False)
这一部分,我们实现最简单的保存&读取变量值
save = tf.train.Checkpoint()
save.listed = [fc3_b]
save.mapped = {'fc3_b': save.listed[0]}
save_path = save.save('/home/kesci/work/data/tf_list_example')
print(save_path)
restore = tf.train.Checkpoint()
fc3_b2 = tf.Variable(tf.zeros([10]))
print(fc3_b2.numpy())
restore.mapped = {'fc3_b': fc3_b2}
restore.restore(save_path)
print(fc3_b2.numpy())