前言
早在2017年的时候就想学深度学习框架TensorFlow。那时候TensorFlow火得不了,经常看公司的博士老哥用TensorFlow做着各种高大上的
项目,操着最高端的显卡,做着最炫酷的事情。对神经网络一窍不通的我,只能在旁边站着围观着。那时候我心里想自己一定得抽个时间学学
TensorFlow这玩意,虽然当时做的事情用不上算法,更用不上神经网络、深度学习,但这技术太火了,还是想学下,技多不压身麻。
但是,由于自己对机器学习这玩意不是很感冒(实际是数学功底太差了),学了一段时间机器学习那些东西,比如打打kaggle等等。但自己的数学
还是太差了,连那种所谓的入门西瓜书的公式都看不懂。玩不下去,学着也得不到啥正反馈,后面还是放弃了。
2021年了,今年偶尔上了一个机器学习的网课,才又把当年的那些东西捡起来。这课程要求使用深度学习框架做项目,要么选TensorFlow,要么选
Pytorch。我不知道选哪个,在知乎上搜了下,得出的结论是:Pytorch最近的发展势头要比TensorFlow强劲。
工业界目前TensorFlow占主流,不过,未来可能会被Pytorch超越。在学术界上,Pytorch
领先TensorFlow的。另外,Pytorch对Python比较友好。所以,有了今天这篇文章。我选择了Pytorch。
Pytorch基础
Pytorch Tensor vs Numpy Array
- 在Pytorch中,matrix(array)叫做tensors
33 矩阵,就是一个33tensor
其实这和numpy差不多的:
运行下一下代码:
|
|
- 有些方法numpy 和 pytorch的效果是一样的:12np.ones() = torch.ones()np.random.rand() = torch.rand()
|
|
对于矩阵的构造和操作,感觉用numpy的话可能会更好些。所以,通常会将神经网络的tensor结果转换为numpy array来查看和显示。
可以用如下方法相互转换:
下面是一些数学操作
tensor的加减乘除法:
Variables
- Variables 加速 gradient
- 在神经网络gradient计算时,我们可以用backpropagation, 所以我们需要处理gradients
- variables 和 tensor的区别是 variable累积 gradients
- 我们可以同样用variable做加减乘除运算
- 为了做backward propagation我们需要 variables
|
|
假设我们有等式 y = x^2
定义 x = [2,4] variable
计算后我们得到 y = [4,16] (y = x^2)
概括 o 的等式: o = (1/2)sum(y) = (1/2)sum(x^2)
o 的导数是 x
结果等于 x, 所以gradients是[2,4]
|
|
Logistic Regression
我们看一个数字识别的案例。
- 步骤如下:
- 导入Library
- 准备数据集
- 用MNIST dataset.
- 28*28 images, 10 labels 从 0 到 9
- 数据没有正则化,所以我们要将每个数据除以255. 255是图片的基本正则数值。
- 为了split数据,我们用sklearn的 train_test_split
- 80% train data; 20% test data
- 建立feature和目标tensors. 在下部分,我们通过这些tensors创建variable。另外,我们需要为gradients累积定义variable。
- batch_size意味着比如:我们有1000sample数据,我们可以同时训练1000个 sample,或者,可以把它分成10个group,每个group 100个sample,按顺序训练10个group。batch_size就是group size。
- epoch: 一个epoch意味着一次训练所有的samples
- 实验中,我们有33600 个sample去训练,batch_size定为100. 我们决定epoch设为29(accuracy到29epoch时候已经很高了)。数据被训练29次。问题是需要多少次迭代呢?
训练一次 = 训练33600个sample
但是我们split数据336个group(group_size=batch_size=100),所以1epoch需要336次迭代。我们有29个epoch,所以一共要迭代9744次。 - TensorDataset(): 包装tensors的数据集
- DataLoader(): 包含dataset和sample
- Visualize one of the images in dataset
创建 Logistic Regression模型
实例模型
- input_dim = 28 * 28 # size of image pxpx
- output_dim = 10 # labels 0,1,2,3,4,5,6,7,8,9
- create model
- 实例 Loss
- Cross entropy loss
- 实例 Optimizer
- SGD Optimizer
- Traning the Model
- Prediction
代码如下:
|
|
- Training part123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657# Traning the Modelcount = 0loss_list = []iteration_list = []for epoch in range(num_epochs):for i, (images, labels) in enumerate(train_loader):# Define variablestrain = Variable(images.view(-1, 28*28))labels = Variable(labels)# Clear gradientsoptimizer.zero_grad()# Forward propagationoutputs = model(train)# Calculate softmax and cross entropy lossloss = error(outputs, labels)# Calculate gradientsloss.backward()# Update parametersoptimizer.step()count += 1# Predictionif count % 50 == 0:# Calculate Accuracycorrect = 0total = 0# Predict test datasetfor images, labels in test_loader:test = Variable(images.view(-1, 28*28))# Forward propagationoutputs = model(test)# Get predictions from the maximum valuepredicted = torch.max(outputs.data, 1)[1]# Total number of labelstotal += len(labels)# Total correct predictionscorrect += (predicted == labels).sum()accuracy = 100 * correct / float(total)# store loss and iterationloss_list.append(loss.data)iteration_list.append(count)if count % 100 == 0:# Print Lossprint('Iteration: {} Loss: {} Accuracy: {}%'.format(count, loss.data, accuracy))
Artificial Neural Network (ANN)
LR分类可以,但是当复杂度(非线性)增加,准确性就降低了。
所以我们需要增加模型的复杂度。为了增加模型复杂性,我们增加更多非线性方法作为hidden layer。
我们所期待的是,当复杂性增加,我用更多的hidden layer,从而我们的模型准确性会更高。
ANN步骤:
Import Libraries
Prepare Dataset
完全和上一部分一样
用同样的dataset,只需要train_loader and test_loader.
batch size, epoch 和 迭代次数也一样。创建 ANN Model
- 增加3层hidden layer
- 用 ReLU, Tanh and ELU 激活函数。
- Instantiate Model Class
- input_dim = 2828 # size of image pxpx
- output_dim = 10 # labels 0,1,2,3,4,5,6,7,8,9
- hidden layer维度是150,取这个数是随便取的。你可以尝试其他的数值
- create model
- Instantiate Loss
- Cross entropy loss
- It also has softmax(logistic function) in it.
- Instantiate Optimizer
- SGD Optimizer
Traning the Model
Prediction
有了hidden layers 模型的准确率达到了95%。比原来高了很多。
|
|
|
|
Convolutional Neural Network (CNN)
CNN非常适合图像分类
CNN步骤:
- Import Libraries
- Prepare Dataset
- 和前面部分完全相同
- We use same dataset so we only need train_loader and test_loader.
- Convolutional layer:
- 根据filters(kernels)创建feature
- Padding: 在实施filter后,原始图片的维度减少。然而,我们要保留尽可能多的原始图片信息,我们可以在convolutional layer 后,运用padding去增加dimension of feature map。
- 我们用2层convolutional的
- out_channels是16
- Filter(kernel) size is 5*5
- Pooling layer:
- 为convolutional layer(feature map) output准备一个精简的feature map
- 使用2个pooling layer
- Pooling size是: 2*2
Flattening: Flats the features map
Fully Connected Layer:
- 可以是logistic regression,但要以softmax function结尾。
- 我们不会在FC层使用激活函数
- 我们结合convolutional part 和 logistic regression去创建CNN模型
- Instantiate Model Class
- create model
- Instantiate Loss
- Cross entropy loss
- It also has softmax(logistic function) in it.
- Instantiate Optimizer
- SGD Optimizer
Traning the Model
Prediction
convolutional layer准确率高达98%
|
|
Reference
https://www.kaggle.com/kanncaa1/pytorch-tutorial-for-deep-learning-lovers