Task2:从baseline入门深度学习
Part1 深度学习是什么?
深度学习是机器学习的一个分支,它使用神经网络模拟人脑的学习方式,从大量数据中自动学习和提取特征,进行预测和决策。
一个深度学习模型可以看作是由多层神经元组成的模型,而神经元模型包括输入、权重、激活函数和输出。
-
输入就像神经元 树突 接收到的信号,
-
权重则像是调整信号强度的小调节器,
-
激活函数决定是否产生输出,
-
而输出则是传递给其他神经元的信号。
输入、权重和输出都好理解,而激活函数可以看作是是否产生输出和产生什么样的输出的工具。
比如:
就是一个很简单的激活函数,x小于0时无输出,x大于0时不对输出进行任何修改直接输出。
激活函数的种类多种多样,其中比较经典的有:
Part2 深度学习如何训练的?
梯度下降算法
说白了就是找损失函数的最小值,简单理解原理和初高中学的二次函数利用导数找最小值一样,梯度越小说明越接近最小值。
Pytorch训练代码
def train(train_loader, model, criterion, optimizer, epoch):
# switch to train mode
model.train()
end = time.time()
for i, (input, target) in enumerate(train_loader):
input = input.cuda(non_blocking=True)
target = target.cuda(non_blocking=True)
# compute output
output = model(input)
loss = criterion(output, target)
optimizer.zero_grad()
loss.backward()
optimizer.step()
model.train:开启训练模式
input:输入
target:目标
output:输出
loss:f(输出,目标)
zero_grad():置零
loss.backward:反向传播
step:更新参数
Part3 深度学习与迁移学习
迁移学习是一种机器学习技术,它将已在一个任务上学到的知识(如模型参数、特征表示等)应用到另一个相关任务上。
说白了,用一个预训练模型,给点自己的训练数据,进行微调,变成自己需要的模型。
ImageNet 介绍
多样性强的注释数据集,有超过1400万注释过的图像。
实操代码笔记
创建一个张量,形状是2x2。(也可以使用Numpy)
# 直接从数据创建
data = [[1, 2], [3, 4]]
x_data = torch.tensor(data)
x_data.shape
# 从Numpy创建
np_array = np.array(data)
x_data = torch.from_numpy(np_array)
x_data.shape
创建全为1的2x2张量和全为随机数的2x2张量
x_ones = torch.ones_like(x_data) # retains the properties of x_data
print(f"Ones Tensor: \n {x_ones} \n")
x_rand = torch.rand_like(x_data, dtype=torch.float) # overrides the datatype of x_data
print(f"Random Tensor: \n {x_rand} \n")
创建3x4的随机数张量
tensor = torch.rand(3, 4)
print(f"Shape of tensor: {tensor.shape}")
print(f"Datatype of tensor: {tensor.dtype}")
print(f"Device tensor is stored on: {tensor.device}")
检查gpu是否可用
if torch.cuda.is_available():
tensor = tensor.to('cuda')
gpu详细情况
!nvidia-smi
自动求梯度。(说白了,自动求导代码)
# x = torch.ones(2, 2, requires_grad=True)
x = torch.tensor([[1, 2], [3, 4]], dtype=float, requires_grad=True)
print(x)
y = x + 2
print(y)
print(y.grad_fn) # y就多了一个AddBackward
z = y * y * 3
out = z.mean()
print(z) # z多了MulBackward
print(out) # out多了MeanBackward
# out = 0.25 ((x+2) * (x+2) * 3)
画图
import matplotlib.pyplot as plt
from IPython.display import set_matplotlib_formats
set_matplotlib_formats('svg')
# 画图就展示到notebook
%matplotlib inline
# numpy 数值计算、矩阵运算,CPU计算
# tensor 数值计算、矩阵运算 CPU 或 GPU计算
# 准备数据
x = np.linspace(0, 10, 100)
y = -3 * x + 4 + np.random.randint(-2, 2, size=100)
# y = -3x + 4
# y = wx + b
plt.scatter(x, y)
loss:f(输出,目标)
zero_grad():置零
loss.backward:反向传播
step:更新参数之类的代码实现。
w = torch.ones(1, requires_grad=True)
b = torch.ones(1, requires_grad=True)
# 数据
x_tensor = torch.from_numpy(x)
y_tensor = torch.from_numpy(y)
# y = wx + b
def mse(label, pred):
diff = label - pred
return torch.sqrt((diff ** 2).mean())
pred = x_tensor * w + b
loss = mse(y_tensor, pred)
loss # 误差
tensor(21.0296, dtype=torch.float64, grad_fn=<SqrtBackward0>)
# 执行20次参数更新
for _ in range(20):
# 重新定义一下,梯度清空
w = w.clone().detach().requires_grad_(True)
b = b.clone().detach().requires_grad_(True)
# 正向传播
pred = x_tensor * w + b
loss = mse(y_tensor, pred)
print(loss)
loss.backward()
w = w - w.grad * 0.05 # 学习率
b = b - b.grad * 0.05
使用resnet18给出图片最可能的5中分类(类似clip,)
import timm
from PIL import Image
model = timm.create_model('resnet18', pretrained=True)
transform = timm.data.create_transform(
**timm.data.resolve_data_config(model.pretrained_cfg)
)
image_tensor = transform(image)
output = model(image_tensor.unsqueeze(0))
probabilities = torch.nn.functional.softmax(output[0], dim=0)
values, indices = torch.topk(probabilities, 5)
IMAGENET_1k_LABELS = open('imagenet_classes.txt').readlines()
[{'label': IMAGENET_1k_LABELS[idx], 'value': val.item()} for val, idx in zip(values, indices)]
竞赛代码idea
目前在用resnet50跑,看看效果,今天本来想试试simplenet,我感觉simplenet对于这种不需要多样性的单单人脸的判别上还是会有独到之处的,但是huggingface上没有simplenet的预训练模型,kaggle上的notebook用的不太熟练,想通过git clone载入simplenet的模型但是不会,目前在使用colab,但是colab没有记忆功能,实验室服务器还坏了,新服务器的申请许可周五才到,实在头疼。
未来
做一下数据增强,想别的方法提高数据鲁棒性。