TensorFlow学习
为什么要学
论文代码看不懂啊,准备把tensorflow和pytorch的课程都看一下,也不用看太深,能从头到尾写个简单的深度学习流程就行。
简介
为什么要使用TensorFlow
-
GPU加速
- gpu加速表现在,对于大规模矩阵相乘和相加,gpu并行计算比cpu串行计算快很多
-
自动求导
自动求出每一层参数的梯度,更新参数,例如:
## 求解所有参数的梯度 grads = tape.gradient(loss,model.trainable_variables) ## 更新参数 optimizer = optimizers.SGD(learning_rate=0.001) optimizer.apply_gradients(zip(grads,model.trainable_variables)) -
神经网络Layers
调用TensorFlow的api完成复杂神经网络的搭建
安装
- Anaconda
- CUDA Nvidia运算平台,实现并行计算
- cuDNN 面向神经网络的加速库
应用
以手写数字识别为例,训练神经网络的步骤为
- 准备数据集minist
- 前向传播计算h1、h2、out
- 由y和out计算loss
- 由loss计算梯度,更新参数w1、b1、w2、b2、w3、b3
- 跳到第二步,用更新好的参数继续计算
以具体的例子可以对比使用tensorflow前后的不同
note
-
要使用GPU加速,要将numpy转换为tensor
-
为了解决高维数据的吞吐和运算,list——>numpy.array
为了支持GPU运算和自动求导, numpy.array——>tf.Tensor
-
tf.varible()是专门为神经网络的参数设置的属性,为了记录参数的梯度信息
tensorflow基础
基本数据类型和属性
-
为了解决高维数据的吞吐和运算,list——>numpy.array
-
为了支持GPU运算和自动求导, numpy.array——>tf.Tensor
-
tf.varible()是专门为神经网络的参数设置的属性,为了记录参数的梯度信息
-
类型转换:tf.cast
创建Tensor以及不同维度Tensor的应用
-
创建tensor ,用于初始化
-
[]是标量
-
不同维的Tensor对应不同的应用场景,比如三维用在NLP中,四维用在图片中
-
tf.random.uniform均匀分布的随机数
-
tf.random.norm正态分布的随机数
索引和切片和采样
- 三种索引方式
维度变换
- 维度不一致可以用broadcasting,可以自动运算不一致的维度,但是有限制
数学运算
- +-*/ (元素操作)
- ** ,pow,square
- sqrt
- //,%
- exp,log
- @,matmul (矩阵操作)
- linear layer
- reduce_mean/max/min/sum (维度操作)
操作
前向传播
张量的高级操作
- 合并与分割
- 数据统计
tf.norm(a)相当于tf.sqrt(tf.reduce_sum(tf.square(a)))- tf.equal和tf.argmax可以用于求解预测的准确性
- 排序
- 填充与复制
- tf.pad 用于对图片数据和语言数据的扩充
- tf.tile
全连接层
#张量方式实现
x = tf.random.normal([2,784])
w1 = tf.Variable(tf.random.truncated_normal([784, 256], stddev=0.1))
b1 = tf.Variable(tf.zeros([256]))
o1 = tf.matmul(x,w1) + b1 # 线性变换
o1 = tf.nn.relu(o1) # 激活函数
#layer方式实现
x = tf.random.normal([4,28*28])
from tensorflow.keras import layers # 导入层模块
fc = layers.Dense(512, activation=tf.nn.relu) # 创建全连接层,指定输出节点数和激活函数
h1 = fc(x) # 通过 fc 类实例完成一次全连接层的计算,返回输出张量
#多层全连接层
from tensorflow.keras import layers,Sequential
model = Sequential([# 通过 Sequential 容器封装为一个网络类
layers.Dense(256, activation=tf.nn.relu) , # 创建隐藏层 1
layers.Dense(128, activation=tf.nn.relu) , # 创建隐藏层 2
layers.Dense(64, activation=tf.nn.relu) , # 创建隐藏层 3
layers.Dense(10, activation=None) , # 创建输出层
])
可视化
-
Tensorboard
#在存放数据的文件夹下 cmd 输入 tensorboard --logdir logs #build summary current_time = datatime.datetime.now().striftime("%Y%m%d-%H%M%S") log_dir = 'logs/' + current_time summary_writer = tf.summary.create_file_writer(log_dir) #fed scalar with summary_writer.as_default(): tf.summary.scalar('loss',float(loss),step=epoch) tf.summary.scalar('accuracy',float(train_accuracy),step=epoch) #fed single Image with summary_writer.as_default(): tf.summary.image("Training sample:",sample_image,step = 0) -
visdom
keras高层接口
主要接口与接口下的函数
from tensorflow.keras import optimizers,losses,datasets,layers,Sequntial,...
-
datasets
-
layers 层模块 包含Dense和Relu等函数
-
losses
-
metrics
-
optimizers
-
Sequential 网络容器,是keras.Model的子类,用于多层神经网络 ,包含build加载模型等函数
-
trainable_varibles
-
call()为network(x)前向计算自动调用的函数
-
compile、fit 和evaluate分别用于模型装配、训练和测试
##使用compile、fit之前的模型装配、训练和测试,详细见ch08-Keras高层接口/metrics.py network = Sequential([layers.Dense(256, activation='relu'), layers.Dense(128, activation='relu'), layers.Dense(64, activation='relu'), layers.Dense(32, activation='relu'), layers.Dense(10)]) network.build(input_shape=(None, 28*28))#创建参数,方便在训练之前观察参数,而network(x)可以自动创建参数并实现前向计算 optimizer = optimizers.Adam(lr=0.01) acc_meter = metrics.Accuracy()##准确率 for step, (x,y) in enumerate(db): with tf.GradientTape() as tape: x = tf.reshape(x, (-1, 28*28)) out = network(x) y_onehot = tf.one_hot(y, depth=10) loss = tf.reduce_mean(tf.losses.categorical_crossentropy(y_onehot, out, from_logits=True)) grads = tape.gradient(loss, network.trainable_variables) optimizer.apply_gradients(zip(grads, network.trainable_variables)) # evaluate if step % 500 == 0: total, total_correct = 0., 0 acc_meter.reset_states() for step, (x, y) in enumerate(ds_val): x = tf.reshape(x, (-1, 28*28)) out = network(x) pred = tf.argmax(out, axis=1) pred = tf.cast(pred, dtype=tf.int32) correct = tf.equal(pred, y) total_correct += tf.reduce_sum(tf.cast(correct, dtype=tf.int32)).numpy() total += x.shape[0] acc_meter.update_state(y, pred) print(step, 'Evaluate Acc:', total_correct/total, acc_meter.result().numpy())###使用compile、fit之后的模型装配、训练和测试,详细见ch08-Keras高层接口/nb.py network = Sequential([layers.Dense(256, activation='relu'), layers.Dense(128, activation='relu'), layers.Dense(64, activation='relu'), layers.Dense(32, activation='relu'), layers.Dense(10)]) network.build(input_shape=(4, 28*28)) from tensorflow.keras import optimizers,losses # 采用Adam优化器,学习率为0.01;采用交叉熵损失函数,包含Softmax network.compile(optimizer=optimizers.Adam(lr=0.01), loss=losses.CategoricalCrossentropy(from_logits=True), metrics=['accuracy'] # 设置测量指标为准确率 ) # 指定训练集为db,验证集为val_db,训练5个epochs,每2个epoch验证一次 history = network.fit(train_db, epochs=5, validation_data=val_db, validation_freq=2) network.evaluate(ds_val) history.history # 打印训练记录
-
自定义网络和自定义网络层
自定义网络需要继承自keras.Model基类,自定义网络层需要继承自keras.layers.Layer基类
- 自定义网络层,重写
__init__和call - 自定义网络,重写cal,可以使用Model的compile、fit、evaluate
保存模型
- 第一种方式,保存模型参数信息
#保存模型参数
model.save_weights('./checkpoints/my_checkpoint')
#重新建立模型
#载入模型参数
network.load_weights('./checkpoints/my_checkpoint')
- 第二种方式,保存模型结构和模型参数
network.save('model.h5')
del network
network = keras.models.load_model('model.h5')
- 第三种方式
# 具有平台无关性
tf.saved_model.save(network, 'model-savedmodel')
del network
network = tf.saved_model.load('model-savedmodel')
卷积神经网络
- 通过滑动窗口和参数共享来减少神经网络的参数,从而加深网络深度
- 卷积层还起到一个降为的功能,如果stride设的大的话
- 金字塔的结构一层一层的堆叠的作用:获得低层特征到获得高层抽象特征