预备知识
ndarray
#mask
X<Y,X>Y
#3*5*2与3*5张量进行求和,3*5广播为3*5*2
XX=tf.constant([[[1,2,3],[2,4,5],[3,4,5],[4,5,6],[5,6,7]],[[1,2,3],[2,4,5],[3,4,5],[4,5,6],[5,6,7]]])
YY=tf.constant([[1,2,3],[2,4,5],[3,4,5],[4,5,6],[5,6,7]])
XX,YY,XX+YY
pandas
pandas api doc https://pandas.pydata.org/docs/reference/index.html
#主要api位于Series模块
dataAfterDeleteMaxNan=data.drop(labels=data.isnull().sum().idxmax() ,axis=1)
print(dataAfterDeleteMaxNan)
dataAfterDeleteMaxNan.fillna(data.mean())
tf.constant(pd.get_dummies(dataAfterDeleteMaxNan, dummy_na=True))
linear-algebra
#1
X=tf.reshape(tf.range(20, dtype=tf.dtypes.float32), (5, 4))
X_t=tf.transpose(X)
X_t_t=tf.transpose(X_t)
print(X==X_t_t)
#2
Y=tf.reshape(tf.ones(20),(5,4))
Y_t=tf.transpose(Y)
print(tf.transpose(X+Y)==X_t+Y_t)
#3
Z=tf.random.normal ((5,5), dtype=tf.dtypes.float32)
Z_t=tf.transpose(Z)
ZpZ_t=Z+Z_t
print(ZpZ_t==tf.transpose(ZpZ_t))
#4
X=tf.reshape(tf.range(24, dtype=tf.dtypes.float32), (2, 3,4))
print(len(X))
#5
X=tf.reshape(tf.range(60, dtype=tf.dtypes.float32), (5, 3,4))
print(len(X))
#6 不是同形状 需要广播
#A/tf.reduce_sum(A, axis=[1])
#7 在哪个维度求和就去掉那个维度
X=tf.reshape(tf.range(24, dtype=tf.dtypes.float32), (2, 3,4))
print(X,tf.reduce_sum(X, axis=0),tf.reduce_sum(X, axis=1),tf.reduce_sum(X, axis=2))
#8 norm指定维度则将指定维度忽略
tf.norm(X,axis=0),tf.norm(X,axis=1),tf.norm(tf.norm(X,axis=0),axis=0),tf.norm(tf.norm(tf.norm(X,axis=0),axis=0)),tf.norm(X)
calculus
#1
def f(x):
return x**3 - 1/x
def numerical_lim(f, x, h):
return (f(x + h) - f(x)) / h
plot(x, [f(x),numerical_lim(f,1,0.0001)*(x-1)+f(1) ], 'x', 'f(x)', legend=['f(x)', 'Tangent line (x=1)'])
#2
def f1(x):
return 3*x**2+5*np.exp(x**2)
numerical_lim(f1, x, 0.001)
plot(x, [numerical_lim(f1, x, 0.001)], 'x', 'f(x)', legend=['f(x)'])
autograd
#2 运行出错 非持久的GradientTape只能用于计算一组梯度(或雅可比矩阵)
with tf.GradientTape(persistent=True) as t:
y = x * x
print(t.gradient(y, x) )
#3
from d2l import tensorflow as d2l
import math
#5
t.gradient(y, x)
x = tf.Variable(tf.range(0, 9, 0.1))
with tf.GradientTape() as t:
y = tf.math.sin(x)
# 生成图形
d2l.plot(x.numpy(), [tf.math.sin(x).numpy(), t.gradient(y, x).numpy()], 'x', "", legend=['f(x)', "f'(x)"])
线性神经网络
linear-regression-scratch
#1 权重初始化为0无法通过梯度下降来计算梯度
#2 固定电阻 测算不同电压下电流的值 电压值作为feature 电流作为label 由于先验知识可得该线性模型没有bias
#5 数组与一维张量不等价
#7
def data_iter(batch_size, features, labels):
#获取features长度
num_examples = len(features)
#获取从0到features长度大小的索引列表
indices = list(range(num_examples))
# 这些样本是随机读取的,没有特定的顺序
#打乱索引
random.shuffle(indices)
#从0到num_examples 步长 为batch_size 如果样本数量不能整除batch_size 则会浪费一些样本
for i in range(0, num_examples, batch_size):
j = tf.constant(indices[i: min(i + batch_size, num_examples)])
yield tf.gather(features, j), tf.gather(labels, j)
linear-regression-concise
#1
initializer = tf.initializers.RandomNormal(stddev=0.01)
net = tf.keras.Sequential()
net.add(tf.keras.layers.Dense(1, kernel_initializer=initializer))
loss = tf.keras.losses.Huber()
trainer = tf.keras.optimizers.SGD(learning_rate=0.03)
num_epochs = 3
for epoch in range(num_epochs):
for X, y in data_iter:
with tf.GradientTape() as tape:
l = loss(net(X, training=True), y)
grads = tape.gradient(l, net.trainable_variables)
trainer.apply_gradients(zip(grads, net.trainable_variables))
l = loss(net(features), labels)
print(f'epoch {epoch + 1}, loss {l:f}')
softmax-regression
image-classification-dataset
#1 会影响性能 需要进行多次切割与打乱
#2
softmax-regression-scratch
#1 754浮点数表示范围
#2 对数函数自变量应大于0
#3 问题一归一化 问题二加上一个极小值
#4 计算复杂度提升
softmax-regression-concise
多层感知机
mlp
#1
x = tf.Variable(tf.range(-8.0, 8.0, 0.1), dtype=tf.float32)
net=tf.keras.layers.PReLU();
y = net(x)
with tf.GradientTape() as t:
y = net(x)
d2l.plot(x.numpy(), t.gradient(y, x).numpy(), 'x', 'prelu(x)', figsize=(5, 2.5))
#4 小批量将导致分布不均
mlp-scratch
#1 num_hiddens参数 单层weight数目增加可能导致过拟合,提高深度比提高广度效果更好
#2 更多的隐藏程即加深网络结构深度
#3 lr过大将导致收敛变慢 过小则无法进行学习
#4
#5
#6
mlp-concise
#1
#2 sigmoid对初始值很敏感 10个epoch效果都不好
#3 需要根据不同的激活函数来进行初始化权重 relu一般使用He初始值
underfit-overfit
#1
#2
#3 梯度爆炸
#4 在有随机噪声的情况下 就算对训练数据完全拟合 也不可能再测试数据上完全拟合
weight-decay
#1 labmda用于控制惩罚程度 lambda越大则初始损失越大 梯度则越大 梯度过大将导致颠簸 无法收敛至最低点
#2 在同分布的情况下 可以在验证集找lambda
#3 将L2正则项替换为L1
#4
#5 Dropout
#6
dropout
#1 若首层概率较大则会损失产生较大颠簸现象
#2 增加训练轮数后 不使用dropout时test acc仍然会持续产生颠簸
#3
#4 暂退法具有随机性 测试时使用暂退法 无法评估模型
#5 两者叠加后曲线更加的平缓了
#6 若激活函数是relu 将导致激活后输出更多的0 输出0的概率比置于激活函数后增加
#7
backprop
numerical-stability-and-init
environment
kaggle-house-price
深度学习计算
model-construction
#1 不是很理解,原文中实现本来就是list
#2
class parallelBlock(tf.keras.Model):
def __init__(self,block1,block2):
super().__init__()
self.block1 = block1
self.block2 = block2
def call(self, X):
return tf.concat([self.block1(X),self.block2(X)],0)
net = tf.keras.Sequential()
net.add(parallelBlock(block1= tf.keras.layers.Dense(64, activation=tf.nn.relu),block2= tf.keras.layers.Dense(64, activation=tf.nn.relu)))
net(X)
#3
def genereteMultiBlock(num):
net=tf.keras.Sequential()
for i in range(num):
net.add(parallelBlock(block1= tf.keras.layers.Dense(64, activation=tf.nn.relu),block2= tf.keras.layers.Dense(64, activation=tf.nn.relu)))
return net
net = tf.keras.Sequential()
net.add(genereteMultiBlock(3))
net,net(X)
parameters
#1
class FixedHiddenMLP(tf.keras.Model):
def __init__(self):
super().__init__()
self.flatten = tf.keras.layers.Flatten()
# 使用`tf.constant`函数创建的随机权重参数在训练期间不会更新(即为常量参数)
self.rand_weight = tf.constant(tf.random.uniform((20, 20)))
self.dense = tf.keras.layers.Dense(20, activation=tf.nn.relu)
def call(self, inputs):
X = self.flatten(inputs)
# 使用创建的常量参数以及`relu`和`matmul`函数
X = tf.nn.relu(tf.matmul(X, self.rand_weight) + 1)
# 复用全连接层。这相当于两个全连接层共享参数。
X = self.dense(X)
# 控制流
while tf.reduce_sum(tf.math.abs(X)) > 1:
X /= 2
return tf.reduce_sum(X)
X = tf.random.uniform((2, 20))
net = tf.keras.Sequential()
net.add(FixedHiddenMLP())
net(X)
print(net.summary())
print(net.layers[0].summary())
print(net.layers[0].layers[1].get_weights())
#2 https://www.tensorflow.org/api_docs/python/tf/keras/initializers
#3
#4 有效减少网络参数数量,减小复杂度,防止过拟合
deferred-init
#会立即进行初始化
net = tf.keras.models.Sequential([
tf.keras.layers.Dense(256, activation=tf.nn.relu,input_shape=(16,)),
tf.keras.layers.Dense(10),
])
print(net.summary())
[net.layers[i].get_weights() for i in range(len(net.layers))]
#2 tf可以自行推断
#3
custom-layer
#1
read-write
#1 不需要从头训练
#2 保存之前网络前两层的参数 新声明的网络时读取文件自定义前两层的参数
#3 保存为HDF5格式
use-gpu
#1 小计算量任务不占满cpu核心数情况下 主频越高计算越快
卷积神经网络
why-conv
#1
#2 减少了空间特征
#3 补齐
#4 对于频谱图进行卷积
#5 不太适合 空间特征没有图片强烈
conv-layer
#1 对角矩阵的转置等于其本身
X = tf.Variable(tf.linalg.diag (tf.ones([4])))
K = tf.constant([[0.5, 0],[0, 0.5]])
Y = corr2d(X, K)
Y
corr2d(tf.transpose(X), K)
#2
#3
#4
padding-and-strides
#1
conv2d = tf.keras.layers.Conv2D(1, kernel_size=(3,5), padding='valid',
strides=(3, 4))
X,comp_conv2d(conv2d, X),conv2d.get_weights(),comp_conv2d(conv2d, X).shape
#2
#3 采样率
#4 减少复杂度
channels
#1 感觉和线性结构一个道理
#2
pooling
#1 可以 kernel的权重为窗口大小分之一
#2 不行 没办法通过指定不一样的权重来实现
#3
#4 运算逻辑不一样
#5
lenet
#1 感觉损失函数收敛的更快了
现代卷积神经网络
alexnet
#迭代20次 精确度增加有限
#2
def net():
return tf.keras.models.Sequential([
# 这里,我们使用一个11*11的更大窗口来捕捉对象。
# 同时,步幅为4,以减少输出的高度和宽度。
# 另外,输出通道的数目远大于LeNet
tf.keras.layers.Conv2D(filters=24, kernel_size=11, strides=4,
activation='relu'),
tf.keras.layers.MaxPool2D(pool_size=3, strides=2),
# 减小卷积窗口,使用填充为2来使得输入与输出的高和宽一致,且增大输出通道数
tf.keras.layers.Conv2D(filters=64, kernel_size=5, padding='same',
activation='relu'),
tf.keras.layers.MaxPool2D(pool_size=3, strides=2),
# 使用三个连续的卷积层和较小的卷积窗口。
# 除了最后的卷积层,输出通道的数量进一步增加。
# 在前两个卷积层之后,汇聚层不用于减少输入的高度和宽度
tf.keras.layers.Conv2D(filters=128, kernel_size=3, padding='same',
activation='relu'),
tf.keras.layers.Conv2D(filters=128, kernel_size=3, padding='same',
activation='relu'),
tf.keras.layers.Conv2D(filters=64, kernel_size=3, padding='same',
activation='relu'),
tf.keras.layers.MaxPool2D(pool_size=3, strides=2),
tf.keras.layers.Flatten(),
# 这里,全连接层的输出数量是LeNet中的好几倍。使用dropout层来减轻过拟合
tf.keras.layers.Dense(1024, activation='relu'),
tf.keras.layers.Dropout(0.5),
tf.keras.layers.Dense(1024, activation='relu'),
tf.keras.layers.Dropout(0.5),
# 最后是输出层。由于这里使用Fashion-MNIST,所以用类别数为10,而非论文中的1000
tf.keras.layers.Dense(10)
])
lr, num_epochs = 0.01, 20
d2l.train_ch6(net, train_iter, test_iter, num_epochs, lr, d2l.try_gpu())
#3 显存占用肯定会增加 但是ipython kernel默认占据了很多显存 故看不出差别 精度变化不大
vgg
#1 打印出的是嵌套层输出尺寸
#2 卷积层更多 且维度更大
#3
#4
conv_arch = ((2, 64), (2, 128), (3, 256), (3, 512), (3, 512))
net = vgg(conv_arch)
nin
googlenet
batch-norm
resnet
densenet
Comments | NOTHING