本博客记录学习龙书的学习历程:
gtitub :https://github.com/dragen1860/Deep-Learning-with-TensorFlow-book
向开源大神致敬!
1.感知机
2.全连接层
2.1 用张量方式实现全连接层,要求:输入为2个样本,784维特征值,输出维256个特征。激活函数使用relu函数。
# 创建 W,b 张量
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)
o1
2.2 使用层方式实现
x = tf.random.normal([4,28*28])
from tensorflow.keras import layers # 导入层模块
# 创建全连接层,指定输出节点数和激活函数
fc = layers.Dense(512, activation=tf.nn.relu)
h1 = fc(x) # 通过 fc 类实例完成一次全连接层的计算,返回输出张量
3.神经网络
3.1 张量方式实现网络层,输入:[2, 784]隐藏层1:[256]隐藏层2:[128]隐藏层3:[64]输出层:[1, 10]
mport tensorflow as tf
# 定义 x
x = tf.random.normal([2,784])
# 隐藏层 1 张量
w1 = tf.Variable(tf.random.truncated_normal([784, 256], stddev=0.1))
b1 = tf.Variable(tf.zeros([256]))
# 隐藏层 2 张量
w2 = tf.Variable(tf.random.truncated_normal([256, 128], stddev=0.1))
b2 = tf.Variable(tf.zeros([128]))
# 隐藏层 3 张量
w3 = tf.Variable(tf.random.truncated_normal([128, 64], stddev=0.1))
b3 = tf.Variable(tf.zeros([64]))
# 输出层张量
w4 = tf.Variable(tf.random.truncated_normal([64, 10], stddev=0.1))
b4 = tf.Variable(tf.zeros([10]))
with tf.GradientTape() as tape: # 梯度记录器
# x: [b, 28*28]
# 隐藏层 1 前向计算, [b, 28*28] => [b, 256]
h1 = x@w1 + tf.broadcast_to(b1, [x.shape[0], 256])
h1 = tf.nn.relu(h1)
# 隐藏层 2 前向计算, [b, 256] => [b, 128]
h2 = h1@w2 + b2
h2 = tf.nn.relu(h2)
# 隐藏层 3 前向计算, [b, 128] => [b, 64]
h3 = h2@w3 + b3
h3 = tf.nn.relu(h3)
# 输出层前向计算, [b, 64] => [b, 10]
h4 = h3@w4 + b4
# compute gradients
3.2 层方式实现
# 导入常用网络层 layers
from tensorflow.keras import layers, Sequential
fc1 = layers.Dense(256, activation=tf.nn.relu) # 隐藏层 1
fc2 = layers.Dense(128, activation=tf.nn.relu) # 隐藏层 2
fc3 = layers.Dense(64, activation=tf.nn.relu) # 隐藏层 3
fc4 = layers.Dense(10, activation=None) # 输出层
x = tf.random.normal([4, 28 * 28])
h1 = fc1(x) # 通过隐藏层 1 得到输出
h2 = fc2(h1) # 通过隐藏层 2 得到输出
h3 = fc3(h2) # 通过隐藏层 3 得到输出
h4 = fc4(h3) # 通过输出层得到网络输出
print(h4)
# 导入 Sequential 容器
from tensorflow.keras import layers, Sequential
# 通过 Sequential 容器封装为一个网络类
model = 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), # 创建输出层
])
out = model(x) # 前向计算得到输出
4.优化参数
5.激活函数
6.误差计算
7.神经网络
8.汽车油耗预测实战
import tensorflow as tf
import pandas as pd
from tensorflow.keras import layers
dataset_path = tf.keras.utils.get_file("auto-mpg.data", "http://archive.ics.uci.edu/ml/machine-learning-databases/auto-mpg/auto-mpg.data")
column_names = ['MPG','Cylinders','Displacement','Horsepower','Weight',
'Acceleration', 'Model Year', 'Origin']
raw_dataset = pd.read_csv(dataset_path, names=column_names,
na_values = "?", comment='\t',
sep=" ", skipinitialspace=True)
dataset = raw_dataset.copy()
# 查看部分数据
dataset = dataset.dropna() # 删除空白数据项
dataset.head(
其中字段的定义为:
接下来有一个很重要的问题,origin 是一个国家类型字段,它的数值1,2,3代表的是国家。他们之间并没有一个数据距离的关系。 因此我们可以类似与one-hot的思想,按每个类别拆分成特征。
# 处理类别型数据,其中 origin 列代表了类别 1,2,3,分布代表产地:美国、欧洲、日本
# 先弹出(删除并返回)origin 这一列
origin = dataset.pop('Origin')
# 根据 origin 列来写入新的 3 个列
dataset['USA'] = (origin == 1)*1.0
dataset['Europe'] = (origin == 2)*1.0
dataset['Japan'] = (origin == 3)*1.0
dataset.tail() # 查看新表格的后几项
对数据进行测试集和验证集拆分:
# 切分为训练集和测试集
train_dataset = dataset.sample(frac=0.8,random_state=0)
test_dataset = dataset.drop(train_dataset.index)
# 移动 MPG 油耗效能这一列为真实标签 Y
train_labels = train_dataset.pop('MPG')
test_labels = test_dataset.pop('MPG')
# 查看训练集的输入 X 的统计数据
train_stats = train_dataset.describe()
print(train_stats)
对数据进行标准化,并封装训练集
train_stats = train_stats.transpose() # 转置
print(train_stats)
# 标准化数据
def norm(x): # 减去每个字段的均值,并除以标准差
return (x - train_stats['mean']) / train_stats['std']
normed_train_data = norm(train_dataset) # 标准化训练集
normed_test_data = norm(test_dataset) # 标准化测试集
print(normed_train_data.shape,train_labels.shape)
print(normed_test_data.shape, test_labels.shape)
train_db = tf.data.Dataset.from_tensor_slices((normed_train_data.values,
train_labels.values)) # 构建 Dataset 对象
train_db = train_db.shuffle(100).batch(32) # 随机打散,批量化
训练:
from tensorflow.keras import layers,losses
class Network(tf.keras.Model):
# 回归网络模型
def __init__(self):
super(Network, self).__init__()
# 创建 3 个全连接层
self.fc1 = layers.Dense(64, activation='relu')
self.fc2 = layers.Dense(64, activation='relu')
self.fc3 = layers.Dense(1)
def call(self, inputs, training=None, mask=None):
# 依次通过 3 个全连接层
x = self.fc1(inputs)
x = self.fc2(x)
x = self.fc3(x)
return x
model = Network() # 创建网络类实例
# 通过 build 函数完成内部张量的创建,其中 4 为任意设置的 batch 数量,9 为输入特征长度
model.build(input_shape=(4, 9))
model.summary() # 打印网络信息
optimizer = tf.keras.optimizers.RMSprop(0.001) # 创建优化器,指定学习率
for epoch in range(200): # 200 个 Epoch
for step, (x,y) in enumerate(train_db): # 遍历一次训练集
# 梯度记录器,训练时需要使用它
with tf.GradientTape() as tape:
out = model(x) # 通过网络获得输出
loss = tf.reduce_mean(losses.MSE(y, out)) # 计算 MSE
mae_loss = tf.reduce_mean(losses.MAE(y, out)) # 计算 MAE
if step % 10 == 0: # 间隔性地打印训练误差
print(epoch, step, float(loss))
# 计算梯度,并更新
grads = tape.gradient(loss, model.trainable_variables)
optimizer.apply_gradients(zip(grads, model.trainable_variables))
需要着重理解epoch的作用。