1与2的不同
动态图机制:定义的每一个变量,都可以实时获取其状态
装饰器:能够高效,加速(陷阱比较多,建议线上官网看)
keras原来是第三方包,官方主推了·
安装
Tensorflow2.1-cpu安装(缺少msvcp140_1.dll)
tensorflow的tensor排列
model
用的类似pytorch的搭建风格
from tensorflow.keras.layers import Dense, Flatten, Conv2D
from tensorflow.keras import Model
# 创建一个mymodel类继承自model
class MyModel(Model):
def __init__(self):
super(MyModel, self).__init__()
self.conv1 = Conv2D(32, 3, activation='relu')#一个卷积层 Conv2D是tensorflow.keras.layers的,(filters卷积核个数,kernel_sizes卷积核大小,strides 步距高度与宽度,padding有所不同——直接给了vailed和same——不需要时valide(整不完时丢弃)-需要时same,data_format-channel放在哪,activation激活函数,use_bias是否使用偏置,——initializer指定正则化处理)
self.flatten = Flatten()#Flatten层用来将输入“压平”,即把多维的输入一维化,常用在从卷积层到全连接层的过渡
##两个全连接层
self.d1 = Dense(128, activation='relu')
self.d2 = Dense(10, activation='softmax')#自动推理上一层参数,不用设置
#用call来定义正向传播过程
def call(self, x):
x = self.conv1(x) # input[batch, 28, 28, 1] output[batch, 26, 26, 32]
x = self.flatten(x) # output [batch, 21632]
x = self.d1(x) # output [batch, 128]
return self.d2(x) # output [batch, 10]
train
from __future__ import absolute_import, division, print_function, unicode_literals#导入模块
import tensorflow as tf
from model import MyModel
mnist = tf.keras.datasets.mnist#导入数据集mnist是个手写数据集
# download and load data,运行就会下载并载入,会下载到用户.kears里
(x_train, y_train), (x_test, y_test) = mnist.load_data()
x_train, x_test = x_train / 255.0, x_test / 255.0
#查看数据是啥样的
#import numpy as np
#import matplotlib.pyplot as plt
#是numpy的array加载进来的
#imgs=x_test[:3]
#labs=y_test[:3]
#print(labs)
#plot_imgs=np.hstack(imgs)#横向拼接
#plt.imshow(plot_imgs,cmap='gray')#灰度图
#plt.show()
# Add a channels dimension#加入深度信息(keras图像没有)
x_train = x_train[..., tf.newaxis]
x_test = x_test[..., tf.newaxis]
# create data generator数据生成器
train_ds = tf.data.Dataset.from_tensor_slices(#载入数据
(x_train, y_train)).shuffle(10000).batch(32)#把图像与标签合并成元组的方式,shuffle是随机(打乱顺序的10000张 32张为一批,提取一批再打乱一次,再提取)
test_ds = tf.data.Dataset.from_tensor_slices((x_test, y_test)).batch(32)
# create model
model = MyModel()
# define loss
loss_object = tf.keras.losses.SparseCategoricalCrossentropy()#稀疏的多类别交叉熵损失(不是onehot编码)
# define optimizer#adam优化器
optimizer = tf.keras.optimizers.Adam()
# define train_loss and train_accuracy
train_loss = tf.keras.metrics.Mean(name='train_loss')#训练中的平均损失值
train_accuracy = tf.keras.metrics.SparseCategoricalAccuracy(name='train_accuracy')#准确率
# define train_loss and train_accuracy
test_loss = tf.keras.metrics.Mean(name='test_loss')
test_accuracy = tf.keras.metrics.SparseCategoricalAccuracy(name='test_accuracy')
# define train function including calculating loss, applying gradient and calculating accuracy
@tf.function#装饰器#加上之后就不能正常断点调试,因为自动转化成tensorflow的静态图代码,用GPU计算
def train_step(images, labels):#pytorch中会自动跟踪每一个可训练的参数,但tensorflow不会,所以
with tf.GradientTape() as tape:#计算梯度https://blog.csdn.net/Forrest97/article/details/105913952
predictions = model(images)#数据输入模型,得到输出
loss = loss_object(labels, predictions)#上面define loss那里定义的计算损失的函数,计算损失值
gradients = tape.gradient(loss, model.trainable_variables)#经过tf.GradientTape() (tape)的gradinet函数将损失反向传播到模型的每一个可训练参数上,计算误差梯度
optimizer.apply_gradients(zip(gradients, model.trainable_variables))#刚刚定义的adam优化器将每一个节点的误差梯度用于更新该节点的值,zip:将每一个点的误差梯度与参数值打包成一个元组输入进去
train_loss(loss)#用刚刚定义计数器累加器计算历史的损失值
train_accuracy(labels, predictions)
# define test function including calculating loss and calculating accuracy
@tf.function
def test_step(images, labels):
predictions = model(images)
t_loss = loss_object(labels, predictions)
#没有gadient因为不用计算参数更新
test_loss(t_loss)
test_accuracy(labels, predictions)
EPOCHS = 5#迭代5轮
#训练过程
for epoch in range(EPOCHS):
#误差计数器,准确值计数器,不然会把上一轮的历史数据加进来
train_loss.reset_states() # clear history info
train_accuracy.reset_states() # clear history info
test_loss.reset_states() # clear history info
test_accuracy.reset_states() # clear history info
#遍历训练迭代器(train_ds = tf.data.Dataset.from_tensor_slices(#载入数据(x_train, y_train)).shuffle(10000).batch(32)这一句)
for images, labels in train_ds:
train_step(images, labels)#计算误差,反向传播,参数更新(上面定义的)
for test_images, test_labels in test_ds:
test_step(test_images, test_labels)
#每训练完一个epoch之后,就打印信息
template = 'Epoch {}, Loss: {}, Accuracy: {}, Test Loss: {}, Test Accuracy: {}'
print(template.format(epoch + 1,#当前是第几个epoch
train_loss.result(),#损时累加器的历史平均值(result)
train_accuracy.result() * 100,#准确率是个小数
test_loss.result(),
test_accuracy.result() * 100))