Este artículo es una de las notas de estudio del libro "TensorFlow Deep Learning"
Parte teórica
Colección de imágenes de dígitos escritos a mano
La capacidad de generalización de un modelo significa que el modelo también funciona bien en muestras nuevas. Para mejorar la capacidad de generalización, debemos intentar aumentar la escala y la diversidad del conjunto de datos, de modo que el conjunto de datos de entrenamiento que utilizamos para el aprendizaje y la distribución de imágenes digitales reales escritas a mano estén cerca, por ejemplo, todos tienen hábitos diferentes. de números escritos a mano, por lo que debemos hacer todo lo posible. Es posible recopilar imágenes de diferentes estilos de escritura.
Echemos un vistazo al método de representación de la
imagen : una imagen generalmente tiene h filas y w columnas, y cada punto almacena el valor del píxel. El valor del píxel generalmente se expresa como un valor entero para expresar la intensidad del color Yang:
- Imagen en color: use un vector unidimensional de longitud 3 para almacenar los valores R, G y B
- Imagen en escala de grises: solo se necesita un valor para expresar la intensidad, como 0 significa negro puro, 255 significa blanco puro, como se muestra en la siguiente figura
Teniendo en cuenta el formato de entrada, una imagen en escala de grises se almacena en una matriz con una forma de h filas y w columnas, y b imágenes se almacenan usando un tensor de [b, h, w], y luego la matriz se aplana en un vector.
Considere el formato de salida y use la codificación one-hot: si el objeto pertenece a la i-ésima categoría, establezca el índice en la posición i en 1, y establezca la otra posición en 0, como se muestra en la figura:
Dado que existe una relación de tamaño natural entre los números, la ventaja es que es conveniente almacenarlos, por lo que la codificación digital se usa generalmente para el almacenamiento tf.one_hot()
y la codificación one-hot se convierte en una codificación one-hot relativamente escasa para el cálculo.
Cálculo de error
En el problema de clasificación, la función de pérdida de la entropía cruzada de muestreo (entropía cruzada) es mayor y el MSE del problema de regresión se utiliza menos. La función de pérdida se puede definir como:
el objetivo del entrenamiento del modelo es la optimización:
aquí o = W x + bo = Wx + bO=Ancho x+segundo
Modelo no lineal
La capacidad expresiva del modelo lineal es débil y
se puede aprender un modelo más adecuado usando un polinomio cuadrático. Podemos usar una función de activación para convertir el modelo lineal en un modelo no lineal, como la función Sigmoide y la función ReLU. Nuestro objetivo la función se convierte en
o = R e LU (W x + b) o = ReLU (Wx + b)O=R e L U ( ancho x+b )
Parte experimental
Construcción del modelo
# 利用sequential容器封装3个网络层,前一层的输入作为下一层的输出
model = keras.Sequential([
# 创建一层网络,设置输出节点数为256,激活函数为ReLU
layer.Dense(256, activition - 'relu'),
layer.Dense(128, activition - 'relu'),
layer.Dense(10)
])
Código completo
import tensorflow as tf
from tensorflow.keras import datasets, layers, optimizers, Sequential, metrics
# 设置GPU使用方式
# 获取GPU列表
gpus = tf.config.experimental.list_physical_devices('GPU')
if gpus:
try:
# 设置GPU为增长式占用
for gpu in gpus:
tf.config.experimental.set_memory_growth(gpu, True)
except RuntimeError as e:
# 打印异常
print(e)
(xs, ys), _ = datasets.mnist.load_data()
print('datasets:', xs.shape, ys.shape, xs.min(), xs.max())
batch_size = 32
xs = tf.convert_to_tensor(xs, dtype=tf.float32) / 255.
db = tf.data.Dataset.from_tensor_slices((xs, ys))
db = db.batch(batch_size).repeat(30)
model = Sequential([layers.Dense(256, activation='relu'),
layers.Dense(128, activation='relu'),
layers.Dense(10)])
model.build(input_shape=(4, 28 * 28))
model.summary()
optimizer = optimizers.SGD(lr=0.01)
acc_meter = metrics.Accuracy()
for step, (x, y) in enumerate(db):
with tf.GradientTape() as tape:
# 打平操作,[b, 28, 28] => [b, 784]
x = tf.reshape(x, (-1, 28 * 28))
# Step1. 得到模型输出output [b, 784] => [b, 10]
out = model(x)
# [b] => [b, 10]
y_onehot = tf.one_hot(y, depth=10)
# 计算差的平方和,[b, 10]
loss = tf.square(out - y_onehot)
# 计算每个样本的平均误差,[b]
loss = tf.reduce_sum(loss) / x.shape[0]
acc_meter.update_state(tf.argmax(out, axis=1), y)
grads = tape.gradient(loss, model.trainable_variables)
optimizer.apply_gradients(zip(grads, model.trainable_variables))
if step % 200 == 0:
print(step, 'loss:', float(loss), 'acc:', acc_meter.result().numpy())
acc_meter.reset_states()
Resultados experimentales
para resumir
Este experimento utiliza una red neuronal no lineal de 3 capas para la clasificación de imágenes, y su capacidad expresiva es más fuerte que un modelo de regresión lineal de una sola capa. Es muy conveniente usar tensorflow para actualizar los parámetros a través del descenso de gradiente capa por capa, y el efecto final también es muy bueno Tengo una experiencia preliminar del poder del aprendizaje profundo y del tensorflow.