- 截止日期:Fri Apr 25
- 项目内容:本项目是机器学习的入门实践,需构建神经网络完成数字分类等任务。要编辑
models.py
、train.py
、losses.py
文件,并提交至Gradescope。代码将自动评分,会检查逻辑冗余以防止学术不端。遇到问题可联系课程工作人员。
- 依赖项检查:运行
python autograder.py --check-dependencies
,若出现特定窗口(有线段旋转),可跳过此步。需安装numpy
(支持快速处理大型多维数组)、matplotlib
(2D绘图库)、pytorch
(用于创建神经网络)。 - 使用conda环境安装:激活conda环境
conda activate [your environment name]
,然后运行pip install numpy
和pip install matplotlib
。 - 安装Pytorch:激活conda环境后,按Pytorch官网说明,用Conda或Pip下载最新版Pytorch,新手建议用CPU版本。若遇到numpy错误,可降级到
1.24.3
或小于2.0.0
的版本。
tensor()
:将Python列表转换为张量,如tensor(data)
,data
为n维列表。ones(dims...)
:创建指定维度、值全为1的张量,如ones(1,2,3)
生成1×2×3的全1张量。relu(input)
:ReLU激活函数,返回max(input, 0)
。Linear
:用于实现线性层。在__init__
函数中初始化,如self.layer = Linear(输入向量长度, 输出向量长度)
,运行模型时调用self.layer(input)
,Pytorch会自动创建并更新权重。movedim(input_vector, initial_dimension_position, final_dimension_position)
:交换矩阵维度位置,在问题4中有用。cross_entropy(prediction, target)
:分类任务的损失函数,预测与目标差异越大,返回值越高。mse_loss(prediction, target)
:回归任务的损失函数,用法与cross_entropy
类似。
数据以pytorchDataset
对象提供,需转换为pytorch DataLoader
来创建批次数据,如:
data = DataLoader(training_dataset, batch_size = 64)
for batch in data:
# 训练代码写在此处
每个批次数据是{'x':特征, 'label':标签}
形式的字典,label
是基于features
要预测的值。
完成models.py
中的PerceptronModel
类和train.py
中的train_perceptron
函数:
init(self, dimensions)
:初始化PerceptronModel
的权重参数,权重变量需保存为Parameter()
对象,维度为1×dimensions
。forward(self, x)
:计算存储的权重向量与给定输入的点积,返回张量对象。get_prediction(self, x)
:点积非负返回1,否则返回 -1。train_perceptron
:循环遍历数据集,对误分类样本进行更新,当一次遍历无错误时停止训练。
运行python autograder.py -q q1
测试,加--no-graphics
可无图形运行。正确实现无图形运行时,自动评分器应在30秒内完成。
后续要实现非线性回归、手写数字分类、语言识别、带卷积神经网络的手写数字分类等模型。
- 构建神经网络:简单神经网络由线性层和非线性层(如ReLU)组成,可通过调整隐藏层大小、增加层数来构建更复杂网络,但要注意维度匹配、过拟合等问题。
- 批处理:为提高效率需处理批量数据,以线性回归为例展示了批量设置下线性层的实现。
- 随机性:神经网络参数随机初始化,数据可能打乱顺序,可能出现局部最优问题。若连续两次测试未通过,需探索其他架构。
- 设计架构:设计神经网络需反复尝试,可记录架构、超参数及性能;从浅网络开始,找到合适学习率和层大小后再加深网络;注意学习率对模型的影响,不同批量大小可能需要不同学习率;避免网络过宽,注意模型返回值异常情况(如Infinity或NaN) 。推荐超参数范围:隐藏层大小100 - 500,批量大小1 - 128(问题2和3中数据集总大小需能被批量大小整除),学习率0.0001 - 0.01,隐藏层数1 - 3。
通过拟合直线y = 7x0 + 8x1 + 3
展示神经网络框架的工作原理:
- 创建可训练参数:定义权重矩阵
M
和偏置向量B
,对应代码为m = Tensor(2, 1)
和b = Tensor(1, 1)
。 - 计算预测值:定义线性层计算预测值
predicted_y = self.Linear_Layer(x)
。 - 计算损失:用均方误差损失函数
mse_loss
计算损失loss = mse_loss(predicted_y, y)
。 - 训练网络:初始化优化器
optim.Adam(self.parameters(), lr=lr)
,训练时每次迭代需重置梯度、计算预测值、计算损失、计算梯度、更新权重。
完成models.py
中的RegressionModel
类、train.py
中的train_regression
函数和losses.py
中的regression_loss
函数:
RegressionModel.__init__
:完成必要的初始化。RegressionModel.forward
:返回大小为batch_size
×1的节点,代表模型预测。regression_loss
:计算给定预测输出和目标输出的损失。train_regression
:用基于梯度的更新训练模型。
模型损失平均值达到0.02或更小时可得满分,运行python autograder.py -q q2
测试。
完成models.py
中的DigitClassificationModel
类、train.py
中的train_digitclassifier
函数和losses.py
中的digitclassifier_loss
函数:
DigitClassificationModel.forward()
:返回大小为batch_size
×10的节点,分数越高表示数字属于特定类别的概率越高。- 使用
cross_entropy
作为损失函数:不要在网络最后一个线性层使用ReLU激活函数。
模型在测试集上准确率至少达到97%才能得分,运行python autograder.py -q q3
测试。可使用dataset.get_validation_accuracy()
计算验证准确率辅助判断训练停止时机。
完成models.py
中的LanguageIDModel
类、train.py
中的train_langaugeid
函数和losses.py
中的languageid_loss
函数:
- 构建循环神经网络(RNN):处理变长输入,共享参数,对每个字符进行处理,最终将输入单词编码为固定大小向量。
- 批处理:实际应用中需处理批量数据,代码确保同一批次中单词长度相同。
- 设计提示:输入字符为独热编码;从类似之前问题的架构开始设计
finitial(x)
;按特定方法构建f(·, ·)
;隐藏大小d
要足够大;从浅网络开始,确定隐藏大小和学习率后再加深网络。
模型在测试集上准确率至少达到81%才能得满分,运行python autograder.py -q q4
测试。数据集可能存在错误且未过滤不当内容,但参考实现能在验证集上达到89%以上准确率,训练需10 - 20轮。
- 卷积层原理:卷积层可更好处理多维输入的空间信息,通过卷积核与输入矩阵卷积计算输出。
- 任务要求:完成
models.py
中的Convolve
函数,对输入矩阵和权重矩阵进行卷积;完成DigitConvolutionalModel()
类、train.py
中的train_digitconvolution
函数和losses.py
中的digitconvolution_loss
函数。可复用问题3部分代码。
自动评分器先检查convolve
函数,再测试模型在简化MNIST数据集上的准确率是否达到80%。模型训练应相对较快,卷积网络运行可能较慢,但不影响得分。
完成models.py
中的AttentionBlock
类,实现“Scaled Dot - Product Attention”公式softmax\left(M\left(\frac{(Q)(K)^{T}}{\sqrt{d}_{k}}\right)\right)(V)
,其中涉及矩阵乘法、转置等操作,还需应用因果掩码。
构建一个小型生成模型,基于莎士比亚戏剧文本训练,生成下一个字符。需在gpt_model.py
中编辑代码,实现Transformer_Block
类的forward
函数和GPT
类的forward
函数。训练模型运行python chargpt.py
,可尝试调整网络大小、更换训练文本等。
将编辑的Python文件上传至Gradescope,若与他人合作,仅一人提交并标记另一人,避免重复提交被误判为学术不端。工作人员参考解决方案运行完整项目自动评分器约需12分钟,若代码运行时间过长,需检查效率。