tensorflow学习019——Eager模式与自定义训练
变量与自动微分
点击查看代码
import tensorflow as tf
v = tf.Variable(1.0) #创建变量
v.assign(5) #改变变量的值为5
v.assign_add(2) #对变量进行+操作
v.read_value() #读取变量的值
w = tf.Variable([[1.0]])
with tf.GradientTape() as t: #可以跟踪变量的变化
loss = w * w
grad = t.gradient(loss, w) #求解loss对w的微分
print(grad)
#对常量的微分
w = tf.constant(2.0)
with tf.GradientTape() as t:
t.watch(w)
loss = w * w
loss_dw = t.gradient(loss, w)
print(loss_dw)
with tf.GradientTape(persistent=True) as t:
加上上面这行代码中的参数persistent,则后面可以多次调用t.gradient(),不加的话,则调用一次就释放了,后面不能再调用
自定义训练
点击查看代码
import tensorflow as tf
(train_image, train_labels), (test_image, test_labels)= tf.keras.datasets.mnist.load_data()
train_image = tf.expand_dims(train_image,-1) # 原先形状为(60000,28,28),现在变为(60000,28,28,1) 扩展维度,也就是通道维度
# 如果使用参数1,那么形状就变为了(60000,1,28,28)
test_image = tf.expand_dims(test_image,-1)
test_image = test_image / 255
train_image = train_image / 255 # 进行归一化
train_image = tf.cast(train_image, tf.float32) # 将数据类型转换为float,因为只有float才能进行自动微分
test_image = tf.cast(test_image, tf.float32)
train_labels = tf.cast(train_labels,tf.int64)
test_labels = tf.cast(test_labels, tf.int64)
dataset = tf.data.Dataset.from_tensor_slices((train_image,train_labels)) # 将图片和标签进行对应组合,这个函数是将第一维进行拆分
# 也就是可以拆分为60000个单独的数据
dataset = dataset.shuffle(1000).batch(32) # 对数据进行混洗以及绑定32个为一组
test_dataset = tf.data.Dataset.from_tensor_slices((test_image,test_labels))
test_dataset = test_dataset.batch(32)
# 自定义训练,不需要编译模型,是自己写
model = tf.keras.Sequential([
tf.keras.layers.Conv2D(16, [3,3], activation='relu', input_shape=(None,None,1)), # None表示只要是灰度图都可以,没有规定大小
tf.keras.layers.Conv2D(32, [3,3], activation='relu'),
tf.keras.layers.GlobalMaxPool2D(),
tf.keras.layers.Dense(10) # 这里没有进行激活函数,那么就需要再后面的loss函数中进行一些操作
])
optimizer=tf.keras.optimizers.Adam() # 优化器
loss_func = tf.keras.losses.SparseCategoricalCrossentropy(from_logits=True) # 前面没有加入激活函数,这里需要将该参数设为True
def loss(model, x, y): # 计算损失的函数
y_ = model(x)
return loss_func(y,y_)
# 训练网络的一步 也就是单批次的训练过程
# def train_step(model, images, labels): # 计算损失函数和model变量(可训练参数)之间的梯度
# with tf.GradientTape() as t: # 追踪了损失函数
# loss_step = loss(model,images,labels) # 每一步的损失值
# grads = t.gradient(loss_step, model.trainable_variables) # 获得交叉熵损失对网络可训练参数之间的梯度
# optimizer.apply_gradients(zip(grads,model.trainable_variables)) # 优化器用获得梯度来改变可训练参数
#
# def train(epochs):
# for epoch in range(epochs):
# print('Epoch{} is starting'.format(epoch + 1))
# for (batch, (images, labels)) in enumerate(dataset):
# train_step(model,images,labels)
# print(epoch," ",batch)
train_loss = tf.keras.metrics.Mean('train_loss')
train_accuracy = tf.keras.metrics.SparseCategoricalAccuracy('train_accuracy')
test_loss = tf.keras.metrics.Mean('test_loss')
test_accuracy = tf.keras.metrics.SparseCategoricalAccuracy('test_accuracy')
def train_step(model,images,labels):
with tf.GradientTape() as t:
pred = model(images)
loss_step = loss_func(labels,pred)
grads = t.gradient(loss_step,model.trainable_variables)
optimizer.apply_gradients(zip(grads,model.trainable_variables))
train_loss(loss_step)
train_accuracy(labels,pred)
def test_step(model, images, labels):
pred = model(images)
loss_step = loss_func(labels,pred)
test_loss(loss_step)
test_accuracy(labels,pred)
def train(epoches):
for epoch in range(epoches):
for (batch,(images,labels)) in enumerate(dataset):
train_step(model,images,labels)
print('Epoch {}/{} loss is {},accuracy is {}'.format(epoch+1,epoches,train_loss.result(),train_accuracy.result()))
for (batch,(images,labels)) in enumerate(test_dataset):
test_step(model,images,labels)
print('Epoch {}/{} test_loss is {},test_accuracy is {}'.format(epoch+1,epoches,test_loss.result(),test_accuracy.result()))
train_loss.reset_states()
train_accuracy.reset_states()
test_loss.reset_states()
test_accuracy.reset_states()
train(10)
tf.keras.metrics汇总计算模块
点击查看代码
# m = tf.keras.metrics.Mean('acc') # 创建计算均值的对象 acc表示一个名称
# m(10) # 也可以使用m([10,20,30,40])这样的形式
# m(20)
# print(m.result().numpy()) # 会返回15,是10和20的均值
# m.reset_states() # 重置对象,也就是将里面的数值都重置,没有了10和20
# a = tf.keras.metrics.SparseCategoricalAccuracy('acc') # 初始化一个计算正确率的对象
# print(a(labels,model(features))) labels是正确的结果,model是一个模型,可以使用其对features进行预测,由于预测的结果是10个
# 概率值,而SparseCategoricalAccuracy会自动选出其中最大的进行计算
作者:孙建钊
出处:http://www.cnblogs.com/sunjianzhao/
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。