手搓CNN还在尝试中,写了1天还没写完,先把简单的用tensorflow搭建的写出来。
首先处理数据:
import os
import numpy as np
import matplotlib.pyplot as plt
import tensorflow as tf
import cnn_utils
os.environ['TF_CPP_MIN_LOG_LEVEL'] = '2' # 忽略警告
np.random.seed(1)
# 数据处理
train_set_x, train_set_y, test_set_x, test_set_y, classes = cnn_utils.load_dataset()
train_x = train_set_x / 255 # 归一化操作,原图是RGB图像uint8
test_x = test_set_x / 255
def one_hot(y, c):
y_onehot = tf.one_hot(y, c.shape[0])
with tf.Session() as session:
result = session.run(y_onehot)
session.close()
return result
train_y = np.squeeze(one_hot(train_set_y, classes))
test_y = np.squeeze(one_hot(test_set_y, classes))
#print(train_x.shape, train_y.shape, test_x.shape, test_y.shape, classes.shape)
直接建模,绘制损失函数图像,并保存模型:
这边按吴恩达上课演示的模型搭建,2个conv,2个fc,1个softmax
def model(x, y, epoch, batch_size, learning_rate=0.001, beta1=0.9, beta2=0.99):
X = tf.placeholder(tf.float32, shape=[None, x.shape[1], x.shape[2], x.shape[3]], name='X')
Y = tf.placeholder(tf.float32, shape=[None, y.shape[1]], name='Y')
f1 = 5
nc1 = 8
f2 = 5
nc2 = 16
tf.set_random_seed(1)
w1 = tf.get_variable("w1", [f1, f1, X.shape[3], nc1], tf.float32,
initializer=tf.contrib.layers.xavier_initializer())
b1 = tf.get_variable("b1", [nc1], tf.float32, initializer=tf.zeros_initializer())
w2 = tf.get_variable("w2", [f2, f2, nc1, nc2], tf.float32, initializer=tf.contrib.layers.xavier_initializer())
b2 = tf.get_variable("b2", [nc2], tf.float32, initializer=tf.zeros_initializer())
w1x = tf.nn.conv2d(X, w1, [1, 1, 1, 1], padding='VALID')
z1 = tf.nn.bias_add(w1x, b1) # b:一维的Tensor,数据维度和value的最后一维相同。
a1 = tf.nn.relu(z1)
a1_m = tf.nn.max_pool(a1, [1, 2, 2, 1], [1, 2, 2, 1], padding='VALID')
w2a1 = tf.nn.conv2d(a1_m, w2, [1, 1, 1, 1], padding='VALID')
z2 = tf.nn.bias_add(w2a1, b2)
a2 = tf.nn.relu(z2)
a2_m = tf.nn.max_pool(a2, [1, 2, 2, 1], [1, 2, 2, 1], padding='VALID')
a_f = tf.contrib.layers.flatten(a2_m)
a3 = tf.contrib.layers.fully_connected(a_f, 120)
a4 = tf.contrib.layers.fully_connected(a3, 84)
z5 = tf.contrib.layers.fully_connected(a4, 6, activation_fn=None)
cost = tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits(logits=z5, labels=Y))
optimizer = tf.train.AdamOptimizer(learning_rate=learning_rate, beta1=beta1, beta2=beta2).minimize(cost)
init = tf.global_variables_initializer()
saver = tf.train.Saver()
with tf.Session() as sess:
sess.run(init)
costs = []
for i in range(epoch):
# 洗牌
cost_mean = 0
temp = np.random.permutation(x.shape[0])
x_shutter = x[temp, :, :, :]
y_shutter = y[temp, :]
num = int(x.shape[0] / batch_size)
for j in range(num):
x_batch = x_shutter[j * batch_size:(j + 1) * batch_size]
y_batch = y_shutter[j * batch_size:(j + 1) * batch_size]
_, cost_ = sess.run([optimizer, cost], feed_dict={X: x_batch, Y: y_batch})
cost_mean += cost_
cost_mean = cost_mean / num
if x.shape[0] % batch_size != 0:
x_batch = x_shutter[num * batch_size:x.shape[0]]
y_batch = y_shutter[num * batch_size:y.shape[0]]
_, cost_ = sess.run([optimizer, cost], feed_dict={X: x_batch, Y: y_batch})
cost_mean += cost_
cost_mean = cost_mean / 2
if i % 1 == 0:
costs.append(cost_mean)
saver.save(sess, "./Model/model.ckpt")
plt.plot(np.squeeze(costs))
plt.show()
运行:
model(train_x, train_y, 40, 32, 0.001)
读取模型,并评价:
def predict(x, y):
ops.reset_default_graph()
X = tf.placeholder(tf.float32, shape=[None, x.shape[1], x.shape[2], x.shape[3]], name='X')
Y = tf.placeholder(tf.float32, shape=[None, y.shape[1]], name='Y')
f1 = 5
nc1 = 8
f2 = 5
nc2 = 16
tf.set_random_seed(1)
w1 = tf.get_variable("w1", [f1, f1, X.shape[3], nc1])
b1 = tf.get_variable("b1", [nc1])
w2 = tf.get_variable("w2", [f2, f2, nc1, nc2])
b2 = tf.get_variable("b2", [nc2])
w1x = tf.nn.conv2d(X, w1, [1, 1, 1, 1], padding='VALID')
z1 = tf.nn.bias_add(w1x, b1) # b:一维的Tensor,数据维度和value的最后一维相同。
a1 = tf.nn.relu(z1)
a1_m = tf.nn.max_pool(a1, [1, 2, 2, 1], [1, 2, 2, 1], padding='VALID')
w2a1 = tf.nn.conv2d(a1_m, w2, [1, 1, 1, 1], padding='VALID')
z2 = tf.nn.bias_add(w2a1, b2)
a2 = tf.nn.relu(z2)
a2_m = tf.nn.max_pool(a2, [1, 2, 2, 1], [1, 2, 2, 1], padding='VALID')
a_f = tf.contrib.layers.flatten(a2_m)
a3 = tf.contrib.layers.fully_connected(a_f, 120)
a4 = tf.contrib.layers.fully_connected(a3, 84)
z5 = tf.contrib.layers.fully_connected(a4, 6, activation_fn=None)
saver = tf.train.Saver()
with tf.Session() as sess:
saver.restore(sess, "./Model/model.ckpt")
correct_prediction = tf.equal(tf.argmax(z5, axis=1), tf.argmax(Y, axis=1))
accuracy = tf.reduce_mean(tf.cast(correct_prediction, "float"))
result = accuracy.eval({X: x, Y: y})
return result
print("测试集的准确率:", predict(test_x, test_y))
print("训练集的准确率:", predict(train_x, train_y))
结果:
测试集的准确率: 0.941667
训练集的准确率: 1.0
好的过分,有点过拟合