AI task01

1.线性回归
一些概念
在机器学习术语里,真实数据集被称为训练数据集(training data set)或训练集(training set),以房价为例,一栋房屋被称为一个样本(sample),其真实售出价格叫作标签(label),用来预测标签的两个因素叫作特征(feature)。特征用来表征样本的特点。
小批量随机梯度下降(mini-batch stochastic gradient descent)在深度学习中被广泛使用。它的算法很简单:先选取一组模型参数的初始值,如随机选取;接下来对参数进行多次迭代,使每次迭代都可能降低损失函数的值。在每次迭代中,先随机均匀采样一个由固定数目训练数据样本所组成的小批量(mini-batch),然后求小批量中数据样本的平均损失有关模型参数的导数(梯度),最后用此结果与预先设定的一个正数的乘积作为模型参数在本次迭代的减小量。
两个向量相加时,应该尽可能采用矢量计算(直接计算),以提升计算效率。

定义优化函数的代码块

ef sgd(params, lr, batch_size): 
    for param in params:
        param.data -= lr * param.grad / batch_size # ues .data to operate param without gradient track

使用图像展示生成的数据

plt.scatter(features[:, 1].numpy(), labels.numpy(), 1);
模型的训练代码自己先理解捋顺关系。
使用pytorch可以简洁实现,但是对于像我这样的初学者来说,最好脚踏实地的走,熟悉库。
可以利用as“改名”来避免命名混乱。

2.softmax和分类模型
softmax回归同线性回归一样,也是一个单层神经网络,softmax回归的输出层也是一个全连接层。
softmax运算符(softmax operator)将输出值变换成值为正且和为1的概率分布,且softmax运算不改变预测类别输出。
广播机制:当两个数组的形状并不相同的时候,我们可以通过扩展数组的方法来实现相加、相减、相乘等操作,这种机制叫做广播(broadcasting)。
广播的原则:如果两个数组的后缘维度(trailing dimension,即从末尾开始算起的维度)的轴长度相符,或其中的一方的长度为1,则认为它们是广播兼容的。广播会在缺失和(或)长度为1的维度上进行。
交叉熵损失函数只关心对正确类别的预测概率,因为只要其值足够大,就可以确保分类结果正确。最小化交叉熵损失函数等价于最大化训练数据集所有标签类别的联合预测概率。
使用准确率(accuracy)来评价模型的表现。它等于正确预测数量与总预测数量之比。
torchvision包主要由以下几部分构成:
torchvision.datasets: 一些加载数据的函数及常用的数据集接口;
torchvision.models: 包含常用的模型结构(含预训练模型),例如AlexNet、VGG、ResNet等;
torchvision.transforms: 常用的图片变换,例如裁剪、旋转等;
torchvision.utils: 其他的一些有用的方法。

对多维Tensor按维度操作的代码块

X = torch.tensor([[1, 2, 3], [4, 5, 6]])
print(X.sum(dim=0, keepdim=True))  # dim为0,按照相同的列求和,并在结果中保留列特征
print(X.sum(dim=1, keepdim=True))  # dim为1,按照相同的行求和,并在结果中保留行特征
print(X.sum(dim=0, keepdim=False)) # dim为0,按照相同的列求和,不在结果中保留列特征
print(X.sum(dim=1, keepdim=False)) # dim为1,按照相同的行求和,不在结果中保留行特征

softmax回归模型

def net(X):
    return softmax(torch.mm(X.view((-1, num_inputs)), W) + b)

定义准确率

def accuracy(y_hat, y):
    return (y_hat.argmax(dim=1) == y).float().mean().item()

定义网络模型代码块(一定要理解)

num_inputs = 784
num_outputs = 10

class LinearNet(nn.Module):
    def __init__(self, num_inputs, num_outputs):
        super(LinearNet, self).__init__()
        self.linear = nn.Linear(num_inputs, num_outputs)
    def forward(self, x): # x 的形状: (batch, 1, 28, 28)
        y = self.linear(x.view(x.shape[0], -1))
        return y
    
# net = LinearNet(num_inputs, num_outputs)

class FlattenLayer(nn.Module):
    def __init__(self):
        super(FlattenLayer, self).__init__()
    def forward(self, x): # x 的形状: (batch, *, *, ...)
        return x.view(x.shape[0], -1)

from collections import OrderedDict
net = nn.Sequential(
        # FlattenLayer(),
        # LinearNet(num_inputs, num_outputs) 
        OrderedDict([
           ('flatten', FlattenLayer()),
           ('linear', nn.Linear(num_inputs, num_outputs))]) # 或者写成我们自己定义的 LinearNet(num_inputs, num_outputs) 也可以
        )

3多层感知机
多个仿射变换的叠加仍然是一个仿射变换,即便再添加更多的隐藏层,以上设计依然只能与仅含输出层的单层神经网络等价。解决问题的一个方法是引入非线性变换,例如对隐藏变量使用按元素运算的非线性函数进行变换,然后再作为下一个全连接层的输入。这个非线性函数被称为激活函数(activation function)。
几个常用的激活函数:
ReLU函数只保留正数元素,并将负数元素清零。
sigmoid函数可以将元素的值变换到0和1之间
tanh(双曲正切)函数可以将元素的值变换到-1和1之间

关于激活函数的选择
ReLu函数是一个通用的激活函数,目前在大多数情况下使用。但是,ReLU函数只能在隐藏层中使用。
用于分类器时,sigmoid函数及其组合通常效果更好。由于梯度消失问题,有时要避免使用sigmoid和tanh函数。
在神经网络层数较多的时候,最好使用ReLu函数,ReLu函数比较简单计算量少,而sigmoid和tanh函数计算量大很多。
在选择激活函数的时候可以先选用ReLu函数如果效果不理想可以尝试其他激活函数。

定义激活函数代码块

def relu(X):
    return torch.max(input=X, other=torch.tensor(0.0))

训练代码块还需要再琢磨一边……

你可能感兴趣的:(学习笔记)