人工智能导论-技术、应用及伦理 实验教案 倪波 模块四 人工神经网络和深度学习_第1页
人工智能导论-技术、应用及伦理 实验教案 倪波 模块四 人工神经网络和深度学习_第2页
人工智能导论-技术、应用及伦理 实验教案 倪波 模块四 人工神经网络和深度学习_第3页
人工智能导论-技术、应用及伦理 实验教案 倪波 模块四 人工神经网络和深度学习_第4页
人工智能导论-技术、应用及伦理 实验教案 倪波 模块四 人工神经网络和深度学习_第5页
已阅读5页,还剩15页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

实验1神经网络基础——感知机、激活函数与反向传播一、实验目的及要求理解人工神经元的数学模型,掌握加权求和、偏置与激活函数的作用。通过实现逻辑门感知机,理解单层感知机的能力与局限(如无法解决XOR问题)。可视化Sigmoid、Tanh、ReLU等常见激活函数,比较其特点与适用场景。动手实现一个包含一个隐藏层的简单神经网络的前向传播与反向传播,理解梯度下降参数更新过程。培养从“规则驱动”到“数据驱动”的范式转变意识。二、实验学时2学时(建议时间分配:讲解10分钟,任务实践70分钟,总结报告10分钟)三、实验前准备软件环境:Python3.8及以上,建议使用JupyterNotebook或VSCode。依赖库:NumPy、Matplotlib。安装命令如下:pipinstallnumpymatplotlib知识储备:已学习教材第5.1、5.2、5.3节内容,了解神经元、激活函数、前向传播与反向传播的基本概念。在JupyterNotebook中运行绘图代码前,建议先执行`%matplotlibinline`,以保证图像正常显示。四、实验任务任务1感知机实现逻辑门(15分钟)使用NumPy实现一个不带激活函数(或带阶跃函数)的感知机,手动设置权重,验证其能否正确实现AND、OR门。任务2单层感知机的局限——XOR问题(10分钟)将XOR真值表输入任务1中的感知机,观察输出结果,解释为什么单层感知机无法解决XOR问题。任务3激活函数可视化(15分钟)绘制Sigmoid、Tanh、ReLU三种激活函数的图像,观察其取值范围、单调性、在原点附近的梯度特性。任务4手动实现两层神经网络求解XOR(25分钟)使用NumPy手动实现一个输入层(2个神经元)+隐藏层(4个神经元,Sigmoid)+输出层(1个神经元,Sigmoid)的神经网络,通过反向传播训练其学会XOR函数。任务5对比scikit-learnMLP(5分钟)使用sklearn.neural_network.MLPClassifier快速求解XOR,体会使用框架的便利性。参考代码以下为完整可运行代码:#实验六:神经网络基础——感知机、激活函数与反向传播

importnumpyasnp

importmatplotlib.pyplotasplt

#设置中文字体

plt.rcParams['font.sans-serif']=['SimHei','MicrosoftYaHei','ArialUnicodeMS']

plt.rcParams['axes.unicode_minus']=False

#====================任务1:感知机实现逻辑门====================

defstep(x):

returnnp.where(x>=0,1,0)

defperceptron(x,w,b):

returnstep(np.dot(x,w)+b)

#训练数据:AND与OR

X=np.array([[0,0],[0,1],[1,0],[1,1]])

#AND门:w1=1,w2=1,b=-1.5

w_and=np.array([1.0,1.0])

b_and=-1.5

print("AND门输出:",perceptron(X,w_and,b_and))

#OR门:w1=1,w2=1,b=-0.5

w_or=np.array([1.0,1.0])

b_or=-0.5

print("OR门输出:",perceptron(X,w_or,b_or))

#====================任务2:单层感知机无法解决XOR====================

y_xor=np.array([0,1,1,0])

print("\nXOR目标:",y_xor)

print("使用AND权重预测XOR:",perceptron(X,w_and,b_and))

print("结论:单层感知机无法用一条直线分开XOR的两类样本。")

#====================任务3:激活函数可视化====================

x=np.linspace(-6,6,400)

plt.figure(figsize=(10,4))

plt.subplot(1,3,1)

plt.plot(x,1/(1+np.exp(-x)))

plt.title("Sigmoid")

plt.grid(True)

plt.subplot(1,3,2)

plt.plot(x,np.tanh(x))

plt.title("Tanh")

plt.grid(True)

plt.subplot(1,3,3)

plt.plot(x,np.maximum(0,x))

plt.title("ReLU")

plt.grid(True)

plt.tight_layout()

plt.show()

#====================任务4:手动实现两层神经网络求解XOR====================

np.random.seed(42)

#网络结构:2->4->1

input_size=2

hidden_size=4

output_size=1

learning_rate=0.5

epochs=10000

#初始化权重与偏置

W1=np.random.randn(input_size,hidden_size)

b1=np.zeros((1,hidden_size))

W2=np.random.randn(hidden_size,output_size)

b2=np.zeros((1,output_size))

defsigmoid(x):

return1/(1+np.exp(-x))

defsigmoid_derivative(x):

returnx*(1-x)

loss_history=[]

forepochinrange(epochs):

#前向传播

z1=np.dot(X,W1)+b1

a1=sigmoid(z1)

z2=np.dot(a1,W2)+b2

a2=sigmoid(z2)

#计算损失(均方误差)

loss=np.mean((y_xor.reshape(-1,1)-a2)**2)

loss_history.append(loss)

#反向传播

d_a2=-(y_xor.reshape(-1,1)-a2)

d_z2=d_a2*sigmoid_derivative(a2)

d_W2=np.dot(a1.T,d_z2)/len(X)

d_b2=np.mean(d_z2,axis=0,keepdims=True)

d_a1=np.dot(d_z2,W2.T)

d_z1=d_a1*sigmoid_derivative(a1)

d_W1=np.dot(X.T,d_z1)/len(X)

d_b1=np.mean(d_z1,axis=0,keepdims=True)

#参数更新(梯度下降)

W2-=learning_rate*d_W2

b2-=learning_rate*d_b2

W1-=learning_rate*d_W1

b1-=learning_rate*d_b1

if(epoch+1)%1000==0:

print(f"Epoch{epoch+1},Loss:{loss:.6f}")

print("\nXOR预测结果:")

print(np.round(a2,3))

plt.figure(figsize=(6,4))

plt.plot(loss_history)

plt.xlabel("迭代次数")

plt.ylabel("损失")

plt.title("训练损失曲线")

plt.grid(True)

plt.show()

#====================任务5:使用scikit-learnMLP求解XOR====================

fromsklearn.neural_networkimportMLPClassifier

mlp=MLPClassifier(hidden_layer_sizes=(4,),activation='tanh',

solver='lbfgs',max_iter=1000,random_state=42)

mlp.fit(X,y_xor)

print("\nMLPClassifierXOR预测:",mlp.predict(X))

预期结果(参考)AND门输出:[0001]

OR门输出:[0111]

XOR目标:[0110]

使用AND权重预测XOR:[0001]

结论:单层感知机无法用一条直线分开XOR的两类样本。

Epoch1000,Loss:0.241226

Epoch2000,Loss:0.183268

Epoch3000,Loss:0.076462

Epoch4000,Loss:0.020962

Epoch5000,Loss:0.009372

Epoch6000,Loss:0.005534

Epoch7000,Loss:0.003767

Epoch8000,Loss:0.002788

Epoch9000,Loss:0.002179

Epoch10000,Loss:0.001770

XOR预测结果:

[[0.03]

[0.96]

[0.956]

[0.051]]

MLPClassifierXOR预测:[0110]结果解读:单层感知机只能解决线性可分问题(AND、OR),无法解决XOR;引入隐藏层后,神经网络可以学习非线性映射,成功解决XOR。结果记录表项目结果结论AND门输出单层感知机可解决OR门输出单层感知机可解决XOR门输出单层感知机无法解决两层网络最终损失随迭代下降两层网络XOR预测接近真实标签Sigmoid取值范围(0,1)Tanh取值范围(-1,1)ReLU负区间输出0五、实验重点、难点重点:感知机的数学模型、激活函数的作用与图像、两层神经网络的前向传播与反向传播流程。难点:理解反向传播中链式法则的应用、梯度下降参数更新公式、XOR问题的非线性本质。六、操作要点建议逐段运行代码,先观察感知机结果,再观察激活函数图像,最后运行XOR神经网络。手动实现XOR网络时,注意损失函数和激活函数导数要对应(本实验使用Sigmoid+MSE)。若训练损失不降,可适当增大学习率或增加迭代次数;若损失震荡,则减小学习率。七、注意事项感知机的阶跃函数不可导,因此不能用于反向传播;手动实现XOR时使用Sigmoid激活函数。神经网络对初始权重敏感,设置随机种子可使结果可复现。本实验为理解原理而设计,实际项目中应优先使用TensorFlow、PyTorch、Keras、scikit-learn等成熟框架。八、实验报告要求填写“结果记录表”。解释为什么单层感知机无法解决XOR问题,并画图说明。描述Sigmoid、Tanh、ReLU三种激活函数各自的优缺点。思考题:如果去掉隐藏层的激活函数(即所有激活函数改为线性函数),两层神经网络还能解决XOR吗?为什么?实验2多层感知机(MLP)手写数字识别一、实验目的及要求掌握使用scikit-learn构建多层感知机(MLP)分类器的方法。理解图像数据预处理流程:尺寸统一、像素归一化、展平与标签编码。掌握MLP的核心超参数:隐藏层结构、激活函数、优化器、学习率、迭代次数、早停等。能够绘制训练/验证损失曲线,识别过拟合与欠拟合现象。理解全连接神经网络处理图像时的局限:参数量大、忽略空间结构。二、实验学时3学时(建议时间分配:讲解15分钟,任务实践130分钟,总结报告15分钟)三、实验前准备软件环境:Python3.8及以上,建议使用JupyterNotebook或VSCode。依赖库:NumPy、Matplotlib、scikit-learn。安装命令如下:pipinstallnumpymatplotlibscikit-learn知识储备:已学习教材第5.3节(前馈神经网络与MLP)内容。数据准备:实验使用scikit-learn内置的load_digits手写数字数据集(8×8像素,1797张),无需联网下载;课后可尝试替换为MNIST数据集。在JupyterNotebook中运行绘图代码前,建议先执行`%matplotlibinline`,以保证图像正常显示。四、实验任务任务1加载与预处理手写数字数据(20分钟)使用sklearn.datasets.load_digits加载手写数字数据集;将像素值除以16进行归一化;数据集本身已是展平的64维向量;将标签转换为整数类型。任务2划分训练集与测试集(10分钟)按8:2划分训练集与测试集。任务3构建与训练MLP模型(40分钟)使用MLPClassifier构建一个具有两个隐藏层的网络(128→64),选择ReLU激活函数和Adam优化器。任务4模型评估与可视化(30分钟)计算测试集准确率、绘制混淆矩阵;随机抽取若干测试样本,对比真实标签与预测结果;可视化部分预测错误的8×8样本。任务5超参数对比实验(30分钟)分别改变隐藏层大小、激活函数、学习率等超参数,观察对训练过程和最终准确率的影响,填写对比表。参考代码以下为完整可运行代码。完整训练通常只需数秒到十几秒,请耐心等待:#实验七:多层感知机(MLP)手写数字识别

importwarnings

warnings.filterwarnings('ignore')

importnumpyasnp

importmatplotlib.pyplotasplt

fromsklearn.datasetsimportload_digits

fromsklearn.model_selectionimporttrain_test_split

fromsklearn.neural_networkimportMLPClassifier

fromsklearn.metricsimportaccuracy_score,confusion_matrix,classification_report

#设置中文字体

plt.rcParams['font.sans-serif']=['SimHei','MicrosoftYaHei','ArialUnicodeMS']

plt.rcParams['axes.unicode_minus']=False

#1.加载手写数字数据集(load_digits为scikit-learn内置数据集,无需联网)

print("正在加载手写数字数据集...")

digits=load_digits()

X=digits.data.astype('float64')/16.0#像素值范围0-16,归一化到[0,1]

y=digits.target

print(f"样本数:{X.shape[0]},特征维度:{X.shape[1]},类别数:{len(np.unique(y))}")

#2.划分训练集与测试集

X_train,X_test,y_train,y_test=train_test_split(

X,y,test_size=0.2,random_state=42,stratify=y

)

print(f"训练样本数:{X_train.shape[0]},测试样本数:{X_test.shape[0]}")

#3.构建MLP模型

mlp=MLPClassifier(

hidden_layer_sizes=(128,64),

activation='relu',

solver='adam',

learning_rate_init=0.001,

max_iter=30,

early_stopping=False,

random_state=42,

verbose=True

)

print("\n开始训练MLP...")

mlp.fit(X_train,y_train)

#4.评估

y_pred=mlp.predict(X_test)

acc=accuracy_score(y_test,y_pred)

print(f"\n测试集准确率:{acc:.4f}")

print("\n分类报告:")

print(classification_report(y_test,y_pred))

#5.绘制训练损失曲线

plt.figure(figsize=(12,5))

plt.subplot(1,2,1)

plt.plot(mlp.loss_curve_,label='训练损失')

plt.xlabel('迭代轮次')

plt.ylabel('损失')

plt.title('MLP训练过程')

plt.legend()

plt.grid(True)

plt.subplot(1,2,2)

cm=confusion_matrix(y_test,y_pred)

plt.imshow(cm,cmap='Blues')

plt.colorbar()

plt.xlabel('预测标签')

plt.ylabel('真实标签')

plt.title('混淆矩阵')

plt.show()

#6.可视化预测错误的样本

errors=np.where(y_pred!=y_test)[0]

print(f"预测错误样本数:{len(errors)}")

plt.figure(figsize=(10,4))

fori,idxinenumerate(np.random.choice(errors,min(8,len(errors)),replace=False)):

plt.subplot(2,4,i+1)

plt.imshow(X_test[idx].reshape(8,8),cmap='gray')

plt.title(f"真实:{y_test[idx]},预测:{y_pred[idx]}")

plt.axis('off')

plt.suptitle('部分预测错误的样本')

plt.tight_layout()

plt.show()预期结果(参考)在1,437条训练样本上训练30个epoch,测试集准确率通常可达0.96–0.98。训练损失曲线应持续下降;若准确率仍不高,可适当增加epoch或增大网络规模。混淆矩阵主对角线颜色最深,说明大多数样本被正确分类;错误样本多为字形相近的数字(如4与9、3与8)。超参数对比表请在下表中填写不同超参数组合下的结果:超参数组合训练时间测试准确率观察与结论hidden=(256,128),relu,adam基线模型hidden=(128,64),relu,adam网络容量减小hidden=(256,128),tanh,adam更换激活函数hidden=(256,128),relu,sgd更换优化器learning_rate_init=0.01学习率增大五、实验重点、难点重点:MLP的构建流程、图像数据归一化与展平、训练/验证损失曲线的解读。难点:理解隐藏层数量与神经元数量对模型容量的影响;识别过拟合与欠拟合;理解全连接网络处理图像时参数量过大的问题。六、操作要点本实验使用scikit-learn内置的load_digits数据集,无需联网下载;课后可尝试替换为MNIST等更大规模数据集。为控制训练时间,课堂演示时可直接使用全部1,437条训练样本;课后可尝试更大规模的手写数字数据。建议记录每次实验的运行时间和最终准确率,便于超参数对比。若出现内存不足,可减少训练样本量或缩小隐藏层规模。七、注意事项MLP将图像展平为向量,丢失了像素间的空间关系,因此参数量大且对平移、旋转的鲁棒性较弱。训练神经网络需要一定时间,不要在课堂上临时安装大型依赖包。测试集只能用于最终评估,不能用于选择模型或调整超参数。早停法使用验证集监控泛化能力,这部分数据应从训练集中划分出来,不能混入测试集。八、实验报告要求记录并解释测试集准确率、混淆矩阵和训练损失曲线。填写“超参数对比表”,分析隐藏层规模、激活函数、优化器、学习率对结果的影响。挑选3–5个预测错误的样本,分析模型为什么会出错。思考题:MLP处理8×8图像时输入层有多少神经元?若将该网络直接应用于28×28的MNIST图像,输入层和第一隐藏层的参数量会发生什么变化?实验3卷积神经网络(CNN)手写数字识别一、实验目的及要求理解卷积神经网络(CNN)的核心思想:局部连接、权值共享、卷积、池化与平移不变性。掌握使用Keras/TensorFlow构建LeNet-5风格CNN的方法。能够对比CNN与MLP在手写数字识别任务上的性能差异,理解CNN在图像任务中的优势。理解CNN的层次化特征学习:浅层学习边缘,中层学习部件,深层学习语义。培养对我国计算机视觉自主创新成果的关注与兴趣。二、实验学时3学时(建议时间分配:讲解15分钟,任务实践130分钟,总结报告15分钟)三、实验前准备软件环境:Python3.8及以上,建议使用JupyterNotebook或VSCode。依赖库:NumPy、Matplotlib、TensorFlow(包含Keras)。安装命令如下:pipinstallnumpymatplotlibtensorflow知识储备:已学习教材第6.3节(卷积神经网络)内容,了解卷积、池化、局部连接与权值共享。说明:TensorFlow安装包较大,建议课前完成安装并验证`importtensorflowastf`无报错;数据集使用scikit-learn内置的load_digits,无需联网下载。在JupyterNotebook中运行绘图代码前,建议先执行`%matplotlibinline`,以保证图像正常显示。四、实验任务任务1加载与预处理手写数字数据(15分钟)使用sklearn.datasets.load_digits加载手写数字数据;将像素值归一化到[0,1];增加通道维度;标签保持整数类型。任务2构建LeNet-5风格CNN(30分钟)搭建网络:卷积层(16个3×3卷积核)→最大池化→卷积层(32个3×3卷积核)→最大池化→展平→全连接层(64)→输出层(10)。理解每一层的作用。任务3训练与评估模型(50分钟)使用Adam优化器和sparse_categorical_crossentropy损失函数训练模型;记录训练过程中的损失与准确率;在测试集上评估最终性能。任务4与MLP对比(15分钟)记录CNN的测试准确率;与实验七中MLP的结果进行对比,分析CNN如何利用局部连接与权值共享提升图像分类效果。任务5可视化卷积核与特征图(20分钟)抽取第一个卷积层的部分卷积核进行可视化;选择一张测试样本,观察其在第一个卷积层输出的特征图,理解CNN如何检测边缘等低级特征。参考代码以下为完整可运行代码。完整训练通常只需十几秒到一分钟(取决于硬件):#实验八:卷积神经网络(CNN)手写数字识别

importwarnings

warnings.filterwarnings('ignore')

importnumpyasnp

importmatplotlib.pyplotasplt

importtensorflowastf

fromtensorflowimportkeras

fromtensorflow.kerasimportlayers

fromsklearn.datasetsimportload_digits

fromsklearn.model_selectionimporttrain_test_split

fromsklearn.metricsimportaccuracy_score,classification_report

#设置中文字体

plt.rcParams['font.sans-serif']=['SimHei','MicrosoftYaHei','ArialUnicodeMS']

plt.rcParams['axes.unicode_minus']=False

print("TensorFlow版本:",tf.__version__)

#1.加载手写数字数据集(load_digits为scikit-learn内置数据集,无需联网)

print("正在加载手写数字数据集...")

digits=load_digits()

X=digits.images.astype('float32')/16.0#像素值范围0-16,归一化到[0,1]

y=digits.target

X=np.expand_dims(X,-1)#增加通道维度->(1797,8,8,1)

print(f"样本数:{X.shape[0]},图像尺寸:{X.shape[1:4]},类别数:{len(np.unique(y))}")

#2.划分训练集与测试集

X_train,X_test,y_train,y_test=train_test_split(

X,y,test_size=0.2,random_state=42,stratify=y

)

print(f"训练样本数:{X_train.shape[0]},测试样本数:{X_test.shape[0]}")

#3.构建CNN模型

model=keras.Sequential([

layers.Input(shape=(8,8,1)),

layers.Conv2D(16,(3,3),activation='relu',padding='same',name='conv1'),

layers.MaxPooling2D((2,2)),

layers.Conv2D(32,(3,3),activation='relu',padding='same',name='conv2'),

layers.MaxPooling2D((2,2)),

layers.Flatten(),

layers.Dense(64,activation='relu'),

layers.Dense(10,activation='softmax')

])

model.summary()

pile(optimizer='adam',

loss='sparse_categorical_crossentropy',

metrics=['accuracy'])

#4.训练

print("\n开始训练CNN...")

history=model.fit(X_train,y_train,epochs=15,batch_size=32,

validation_split=0.1,verbose=1)

#5.评估

test_loss,test_acc=model.evaluate(X_test,y_test,verbose=0)

print(f"\n测试集准确率:{test_acc:.4f}")

y_pred=model.predict(X_test,verbose=0)

y_pred_labels=np.argmax(y_pred,axis=1)

print("\n分类报告:")

print(classification_report(y_test,y_pred_labels))

#6.绘制训练曲线

plt.figure(figsize=(12,5))

plt.subplot(1,2,1)

plt.plot(history.history['loss'],label='训练损失')

plt.plot(history.history['val_loss'],label='验证损失')

plt.xlabel('Epoch')

plt.ylabel('Loss')

plt.title('损失曲线')

plt.legend()

plt.grid(True)

plt.subplot(1,2,2)

plt.plot(history.history['accuracy'],label='训练准确率')

plt.plot(history.history['val_accuracy'],label='验证准确率')

plt.xlabel('Epoch')

plt.ylabel('Accuracy')

plt.title('准确率曲线')

plt.legend()

plt.grid(True)

plt.show()

#7.可视化第一个卷积层的部分卷积核

conv1_weights=model.get_layer('conv1').get_weights()[0]

plt.figure(figsize=(8,4))

foriinrange(16):

plt.subplot(2,8,i+1)

plt.imshow(conv1_weights[:,:,0,i],cmap='gray')

plt.axis('off')

plt.suptitle('第一个卷积层前16个卷积核')

plt.tight_layout()

plt.show()

#8.可视化某张测试样本在conv1输出的特征图

sample=X_test[0:1]

conv1_output_model=keras.Model(inputs=model.layers[0].input,

outputs=model.get_layer('conv1').output)

feature_maps=conv1_output_model.predict(sample,verbose=0)[0]

plt.figure(figsize=(10,4))

plt.subplot(1,9,1)

plt.imshow(sample[0,:,:,0],cmap='gray')

plt.title('原图')

plt.axis('off')

foriinrange(8):

plt.subplot(1,9,i+2)

plt.imshow(feature_maps[:,:,i],cmap='gray')

plt.title(f'特征图{i+1}')

plt.axis('off')

plt.suptitle('输入样本与第一个卷积层特征图')

plt.tight_layout()

plt.show()预期结果(参考)在1,437条训练样本上训练15个epoch,测试集准确率通常可达0.95–0.97,与同规模MLP相比参数量更少且性能相近。训练损失和验证损失同步下降,准确率快速上升。卷积核可视化可观察到边缘、笔画等低级特征检测器;特征图显示网络在数字笔画处响应较强。结果记录表项目MLP(实验七)CNN(本实验)对比分析测试准确率CNN通常更高训练时间与硬件相关输入处理方式64维向量8×8×1张量CNN保留空间结构参数规模CNN通常更少对平移的鲁棒性CNN更强五、实验重点、难点重点:CNN的网络结构(卷积→池化→展平→全连接)、局部连接与权值共享、卷积核与特征图的可视化。难点:理解卷积运算的滑动点积过程、池化层的作用、CNN为何比MLP更适合图像任务。六、操作要点TensorFlow安装包较大,建议课前完成安装;若使用AppleSiliconMac,可安装tensorflow-macos或tensorflow-metal以加速。本实验使用scikit-learn内置的load_digits数据集(1,437条训练样本),建议训练15个epoch;课后可尝试MNIST等更大规模数据。model.summary()可查看每层输出形状和参数量,建议结合教材中的“参数爆炸”问题进行分析。可视化特征图时,选择边缘清晰的样本效果更明显。七、注意事项输入数据的通道维度必须正确:load_digits图像为(8,8,1),MNIST图像为(28,28,1),彩色图为(H,W,3)。卷积核尺寸、步长、填充会影响输出特征图大小,建议结合model.summary()的输出核对。CNN训练需要GPU才能显著加速;CPU上训练可能较慢,请合理安排课堂时间。避免在测试集上调整模型结构或超参数,测试集仅用于最终评估。八、实验报告要求记录CNN的测试准确率,并与实验七的MLP结果进行对比。分析卷积核可视化结果,说明CNN浅层学到了什么特征。解释“局部连接”和“权值共享”如何减少参数并保留空间结构。思考题:load_digits图像是8×8,若直接展平输入全连接层,与CNN相比会有哪些劣势?实验4循环神经网络(RNN)文本情感分类一、实验目的及要求理解循环神经网络(RNN)处理序列数据的基本思想,理解“记忆”与隐藏状态的概念。掌握文本预处理流程:分词、构建词表、序列填充(padding)。掌握使用Keras构建Embedding+LSTM情感分类模型的方法。能够评估模型在测试集上的准确率,并对新评论进行情感预测。理解RNN与CNN/MLP在数据结构和适用场景上的差异。二、实验学时2学时(建议时间分配:讲解10分钟,任务实践70分钟,总结报告10分钟)三、实验前准备软件环境:Python3.8及以上,建议使用JupyterNotebook或VSCode。依赖库:NumPy、Matplotlib、TensorFlow(包含Keras)。安装命令如下:pipinstallnumpymatplotlibtensorflow知识储备:已学习教材第6.4节(循环神经网络)内容,了解序列数据、隐藏状态、LSTM的基本概念。在JupyterNotebook中运行绘图代码前,建议先执行`%matplotlibinline`,以保证图像正常显示。四、实验任务任务1加载与预处理IMDB数据(15分钟)构造模拟情感分析数据集:定义51个词的词汇表(索引0为填充符,1–10为正面词、11–20为负面词、21–50为中性词);生成2,000条评论序列,并用0填充到长度50,使其维度一致。任务2构建Embedding+LSTM模型(15分钟)搭建网络:Embedding层(将词索引映射为16维词向量)→LSTM层(32个单元,dropout=0.2)→Dense输出层(Sigmoid二分类)。任务3训练与评估模型(25分钟)使用Adam优化器和binary_crossentropy损失函数训练模型;记录训练曲线;在模拟测试集上评估准确率。任务4预测新评论情感(10分钟)构造包含较多正面词或负面词的示例序列,预测其情感倾向及置信度。任务5讨论RNN的局限(5分钟)简要讨论RNN的长程依赖问题,以及LSTM如何通过门控机制缓解该问题;提及Transformer作为后续发展方向。参考代码以下为完整可运行代码:#实验九:循环神经网络(RNN)文本情感分类

importwarnings

warnings.filterwarnings('ignore')

importnumpyasnp

importmatplotlib.pyplotasplt

importtensorflowastf

fromtensorflowimportkeras

fromtensorflow.kerasimportlayers

fromtensorflow.keras.preprocessing.sequenceimportpad_sequences

fromsklearn.model_selectionimporttrain_test_split

fromsklearn.metricsimportaccuracy_score,classification_report

#设置中文字体

plt.rcParams['font.sans-serif']=['SimHei','MicrosoftYaHei','ArialUnicodeMS']

plt.rcParams['axes.unicode_minus']=False

print("TensorFlow版本:",tf.__version__)

#1.构造模拟情感分析数据集(无需联网下载)

#词表说明:1-10为正面词,11-20为负面词,21-50为中性词

vocab_size=51

max_len=50

n_samples=2000

np.random.seed(42)

defgenerate_review(label):

length=np.random.randint(25,41)

iflabel==1:#正面评论

n_pos=np.random.randint(7,12)

n_neg=np.random.randint(1,4)

else:#负面评论

n_pos=np.random.randint(1,4)

n_neg=np.random.randint(7,12)

n_neu=length-n_pos-n_neg

words=[]

words.extend(np.random.randint(1,11,size=n_pos).tolist())

words.extend(np.random.randint(11,21,size=n_neg).tolist())

words.extend(np.random.randint(21,51,size=max(0,n_neu)).tolist())

np.random.shuffle(words)

returnwords

all_reviews=[]

labels=[]

for_inrange(n_samples//2):

all_reviews.append(generate_review(1))

labels.append(1)

for_inrange(n_samples//2):

all_reviews.append(generate_review(0))

labels.append(0)

#加入10%标签噪声,模拟真实场景

n_noise=int(0.1*n_samples)

noise_idx=np.random.choice(n_samples,n_noise,replace=False)

foriinnoise_idx:

labels[i]=1-labels[i]

sequences=pad_sequences(all_reviews,maxlen=max_len,padding='post')

labels=np.array(labels)

X_train,X_test,y_train,y_test=train_test_split(

sequences,labels,test_size=0.2,random_state=42

)

print(f"训练样本:{X_train.shape},测试样本:{X_test.shape}")

print(f"词汇表大小:{vocab_size},序列最大长度:{max_len}")

#2.构建Embedding+LSTM模型

model=keras.Sequential([

layers.Input(shape=(max_len,)),

layers.Embedding(input_dim=vocab_size,output_dim=16),

layers.LSTM(32,dropout=0.2,recurrent_dropout=0.2),

layers.Dense(1,activation='sigmoid')

])

model.summary()

pile(optimizer='adam',

loss='binary_crossentropy',

metrics=['accuracy'])

#3.训练

print("\n开始训练LSTM模型...")

history=model.fit(X_train,y_train,epochs=5,batch_size=64,

validation_split=0.1,verbose=1)

#4.评估

test_loss,test_acc=model.evaluate(X_test,y_test,verbose=0)

print(f"\n测试集准确率:{test_acc:.4f}")

y_pred_prob=model.predict(X_test,verbose=0)

y_pred=(y_pred_prob>0.5).astype(int).flatten()

print("\n分类报告:")

print(classification_report(y_test,y_pred,target_names=['负面','正面']))

#5.绘制训练曲线

plt.figure(figsize=(12,5))

p

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论