1. Набор данных
Набор данных использует изображения для распознавания жестов с шестью различными метками от 0 до 5.портал
2. Принципы и методы
- Глубокая нейронная сеть DNN, обученная на наборе данных
- Softmax реализует мультиклассификацию и принимает позицию максимального значения в качестве прогнозируемой метки.
- Горячее кодирование One-hot для реализации векторного отображения меток 0-5
Три, тюнинг-библиотека
import tensorflow as tf
import numpy as np
import tf_utils
import matplotlib.pyplot as plt
from tensorflow.python.framework import ops #用于tf.get_variable重新运行而不覆盖变量
4. Обработка набора данных
(1) Просмотр изображения
train_x, train_y, test_x, test_y, classes = tf_utils.load_dataset()
index = 5
plt.imshow(train_x[index])
print("y =", np.squeeze(train_y[: ,index]))
print("train_x.shape:", train_x.shape)
(2) Уменьшение размерности растяжения
# 降维
train_x_flatten = train_x.reshape(train_x.shape[0], -1).T
test_x_flatten = test_x.reshape(test_x.shape[0], -1).T
print("train_x_flatten.shape:", train_x_flatten.shape)
train_x_flatten.shape: (12288, 1080)
(3) Нормализация
# 归一化
train_x1 = train_x_flatten / 255
test_x1 = test_x_flatten / 255
(4) Однократное кодирование тегов
# 标签独热编码
train_y1 = tf_utils.convert_to_one_hot(train_y, 6)
test_y1 = tf_utils.convert_to_one_hot(test_y, 6)
(5) Просмотр обзора данных
print("训练集样本数:", train_x1.shape[1])
print("测试集样本数:", test_x1.shape[1])
print("训练集图像:", train_x1.shape)
print("训练集标签:", train_y1.shape)
print("测试集图像:", test_x1.shape)
print("测试集标签", test_y1.shape)
训练集样本数: 1080
测试集样本数: 120
训练集图像: (12288, 1080)
训练集标签: (6, 1080)
测试集图像: (12288, 120)
测试集标签 (6, 120)
Пять, каждая функция процесса
# 生成placeholder
def creat_placeholder(n_x, n_y):
x = tf.placeholder(tf.float32, [n_x, None], name="x")
y = tf.placeholder(tf.float32, [n_y, None], name="y")
return x,y
# 初始化参数
def initialize_parameters():
w1 = tf.get_variable("w1",[25,12288],initializer=tf.contrib.layers.xavier_initializer(seed=1))
b1 = tf.get_variable("b1",[25,1],initializer=tf.zeros_initializer())
w2 = tf.get_variable("w2", [12, 25], initializer = tf.contrib.layers.xavier_initializer(seed=1))
b2 = tf.get_variable("b2", [12, 1], initializer = tf.zeros_initializer())
w3 = tf.get_variable("w3", [6, 12], initializer = tf.contrib.layers.xavier_initializer(seed=1))
b3 = tf.get_variable("b3", [6, 1], initializer = tf.zeros_initializer())
# w1 = tf.Variable(tf.random_normal([25, 12288]))
# b1 = tf.Variable(tf.zeros([25, 1]))
# w2 = tf.Variable(tf.random_normal([12, 25]))
# b2 = tf.Variable(tf.zeros([12, 1]))
# w3 = tf.Variable(tf.random_normal([6, 12]))
# b3 = tf.Variable(tf.zeros([6, 1]))
parameters = {
"w1": w1,
"b1": b1,
"w2": w2,
"b2": b2,
"w3": w3,
"b3": b3
}
return parameters
# 前向传播
def forward_propagation(X, parameters):
w1 = parameters["w1"]
b1 = parameters["b1"]
w2 = parameters["w2"]
b2 = parameters["b2"]
w3 = parameters["w3"]
b3 = parameters["b3"]
z1 = tf.matmul(w1, X) + b1
a1 = tf.nn.relu(z1)
z2 = tf.matmul(w2, a1) + b2
a2 = tf.nn.relu(z2)
z3 = tf.matmul(w3, a2) + b3
#a3 = tf.nn.softmax(z3)
return z3
# 计算成本值
def compute_cost(z3, Y):
cost = tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits_v2(logits=tf.transpose(z3), labels=tf.transpose(Y)))
return cost
6. Построение нейросетевой модели
# DNN模型搭建
def nn_model(train_x, train_y, test_x, test_y, learning_rate=0.0001, num_epoch=2000, minibatch_size=32, print_cost=True, is_plot=True):
ops.reset_default_graph()
(n_x, m) = train_x.shape
n_y = train_y.shape[0]
x, y = creat_placeholder(n_x, n_y)
parameters = initialize_parameters()
z3 = forward_propagation(x, parameters)
cost = compute_cost(z3, y)
train = tf.train.AdamOptimizer(learning_rate=learning_rate).minimize(cost)
init = tf.global_variables_initializer()
seed = 3
costs = []
with tf.Session() as session:
session.run(init)
for epoch in range(num_epoch):
epoch_cost = 0
seed = seed + 1
num_minibatch = int(m / minibatch_size)
minibatches = tf_utils.random_mini_batches(train_x, train_y, minibatch_size, seed)
for minibatch in minibatches:
(minibatch_x, minibatch_y) = minibatch
_, minibatch_cost = session.run([train, cost], feed_dict={x:minibatch_x, y:minibatch_y})
epoch_cost = epoch_cost + minibatch_cost / num_minibatch
if epoch%5 == 0:
costs.append(epoch_cost)
if print_cost and epoch%100 == 0:
print("epoch =", epoch, "epoch_cost =", epoch_cost)
if is_plot:
plt.plot(np.squeeze(costs))
plt.title("learning_rate =" + str(learning_rate))
plt.xlabel("epoch")
plt.ylabel("cost")
plt.show()
parameters = session.run(parameters)
correct_prediction = tf.equal(tf.argmax(z3), tf.argmax(y))
accuracy = tf.reduce_mean(tf.cast(correct_prediction, "float"))
print("训练集准确率:", accuracy.eval({x:train_x, y:train_y}))
print("测试集准确率:", accuracy.eval({x:test_x, y:test_y}))
return parameters
7. Подайте набор данных для обучения модели
# 训练模型
parameters = nn_model(train_x1, train_y1, test_x1, test_y1)
epoch = 0 epoch_cost = 1.8915627219460225
epoch = 100 epoch_cost = 1.0814920374841401
epoch = 200 epoch_cost = 0.9045906644878967
epoch = 300 epoch_cost = 0.7937486514900668
epoch = 400 epoch_cost = 0.7092051903406779
epoch = 500 epoch_cost = 0.6288680759343233
epoch = 600 epoch_cost = 0.5487878710934612
epoch = 700 epoch_cost = 0.4825858437653743
epoch = 800 epoch_cost = 0.42227065834132105
epoch = 900 epoch_cost = 0.3695441674102436
epoch = 1000 epoch_cost = 0.31023081188852136
epoch = 1100 epoch_cost = 0.25832218676805496
epoch = 1200 epoch_cost = 0.23583885846715985
epoch = 1300 epoch_cost = 0.1781336689988772
epoch = 1400 epoch_cost = 0.15422452421802463
epoch = 1500 epoch_cost = 0.12832456477212184
epoch = 1600 epoch_cost = 0.10107426119573189
epoch = 1700 epoch_cost = 0.08046883931665708
epoch = 1800 epoch_cost = 0.06646379613966652
epoch = 1900 epoch_cost = 0.05467078682373871
训练集准确率: 0.99722224
测试集准确率: 0.75
8. Предсказание изображения
(1) Прогнозирование образов тренировочного набора
index = 999
x = tf.placeholder(tf.float32, name="x")
plt.imshow(train_x[index])
image = (train_x[index]).reshape(64*64*3, 1) #把图像拉伸降维成列向量
print(image.shape)
with tf.Session() as session:
image_prediction = session.run(forward_propagation(x, parameters), feed_dict={x:image})
prediction_label = np.squeeze(session.run(tf.argmax(image_prediction))) # argmax取softmax分类后向量最大位置
print("prediction_label:", prediction_label)
true_label = np.squeeze(train_y[: ,index])
print("true_label:", true_label)
if prediction_label == true_label:
print("预测结果正确!")
else:
print("预测结果错误!")
(12288, 1)
prediction_label: 2
true_label: 2
预测结果正确!
(2) Предсказать изображение тестового набора
index = 46
x = tf.placeholder(tf.float32, name="x")
plt.imshow(test_x[index])
image = (test_x[index]).reshape(64*64*3, 1)
print(image.shape)
with tf.Session() as session:
image_prediction = session.run(forward_propagation(x, parameters), feed_dict={x:image})
prediction_label = np.squeeze(session.run(tf.argmax(image_prediction)))
print("prediction_label:", prediction_label)
true_label = np.squeeze(test_y[: ,index])
print("true_label:", true_label)
if prediction_label == true_label:
print("预测结果正确!")
else:
print("预测结果错误!")
(12288, 1)
prediction_label: 1
true_label: 2
预测结果错误!
9. Резюме
- Разница между tf.get_variable() и tf.Variable(), первая устанавливается, когда такой переменной нет, и наоборот, переменная возвращается напрямую. Однако при повторном запуске нужно использовать ops для обработки без перезаписи, иначе будет сообщено об ошибке.
- Классификатор Softmax требует несколько единиц вывода, В этом примере требуется шесть единиц вывода, поэтому полученное z3/a3 представляет собой матрицу (6, 1), и argmax можно использовать для получения положения максимального значения, то есть , после однократного кодирования Tag of.
- xavier_initializer инициализирует w: Чтобы поток информации в сети был лучше, дисперсия выходных данных каждого уровня должна быть как можно более равной.
- Функция потери tf.nn.softmax_cross_entropy_with_logits ⚠ не поддерживает версию tf2.0, вы можете использовать: tf.nn.softmax_cross_entropy_with_logits_v2
- tf.nn.softmax_cross_entropy_with_logits_v2(logits=tf.transpose(z3), labels=tf.transpose(Y)) где logits — последний уровень прямого распространения вводаЛинейное выходное значение, метки — это метки после входного одноразового кодирования.
- параметры = session.run(параметры) не бесполезны, поэтому вы можете сохранить окончательные параметры в сеансе.
- Мини-партия случайным образом делится в каждом раунде обучения, и указанное случайное начальное число меняется.
- Результаты обучения можно наблюдать: тренировочный набор работает хорошо, а тестовый набор работает не так хорошо, В тестовом наборе, как в примере на рисунке выше, два пальца 2 очень близко друг к другу, поэтому это очень легко идентифицировать их как 1.
- _, minibatch_cost = session.run([train, cost], feed_dict={x:minibatch_x, y:minibatch_y}) Этот метод написания может запускать функции train и cost одновременно, и функции две в одной.