深度知识追踪(DKT)实现pytorch(及常见问题)

发现代码跑了几遍还是没有自己按照思路写一遍清楚

参考代码

GitHub - dxywill/deepknowledgetracing: Pytorch implementation for Deep Knowledge tracing

论文 https://web.stanford.edu/~cpiech/bio/papers/deepKnowledgeTracing.pdf

数据集介绍

数据形式三行(第一行:答题数
第二行:题目编号(从0开始)
第三行:答题结果,0表示错,1表示对)

data.py

import csv
import random


def load_data(fileName):
    rows = []
    max_skill_num = 0  # max_skill_num是知识点(题目)个数
    max_num_problems = 0  # max_num_problems最长题目序列

    with open(fileName, "r") as csvfile:#打开文件
        reader = csv.reader(csvfile, delimiter=',')
        for row in reader:
            rows.append(row)
    index = 0
    print("the number of rows is " + str(len(rows)))
    tuple_rows = []
    #turn list to tuple
    while(index < len(rows)-1):
        problems_num = int(rows[index][0])
        tmp_max_skill = max(map(int, rows[index+1]))
        if(tmp_max_skill > max_skill_num):
            max_skill_num = tmp_max_skill
        if(problems_num <= 2):#去除了题目小于两个的数据
            index += 3
        else:
            if problems_num > max_num_problems:
                max_num_problems = problems_num
            tup = (rows[index], rows[index+1], rows[index+2])## tup:[题目个数, 题目序列, 答对情况]
            tuple_rows.append(tup)
            index += 3
    #shuffle the tuple
    random.shuffle(tuple_rows)
    print("The number of students is ", len(tuple_rows))
    print("max_skill_num  ", max_skill_num)
    print("max_num_problems  ", max_num_problems)
    print("Finish reading data")
    return tuple_rows, max_num_problems, max_skill_num+1
    #  skill序号从0开始所以最长题目序列为max_skill_num+1
# if __name__ == '__main__':
#     train_data_path='data/test1.csv'
#     load_data(train_data_path)

模型 

class DeepKnowledgeTracing(nn.Module):
    def __init__(self, input_size, hidden_size, num_skills, nlayers, dropout=0.6, tie_weights=False):
        super(DeepKnowledgeTracing, self).__init__()

        
        self.rnn = nn.LSTM(input_size, hidden_size, nlayers, batch_first=True, dropout=dropout)
        # self.rnn = nn.RNN(input_size, hidden_size, nlayers, nonlinearity='tanh', dropout=dropout)

        # nn.Linear是一个全连接层,hidden_size是输入层维数,num_skills是输出层维数
        # decoder是隐层(self.rnn)到输出层的网络
        self.decoder = nn.Linear(hidden_size, num_skills)
        self.nhid = hidden_size
        self.nlayers = nlayers

    # 前向计算, 网络结构是:input --> hidden(self.rnn) --> decoder(输出层)
    # 这里需要注意:在pytorch中,rnn的输入格式已经和tensorflow的rnn不太一样,具体见官网:
    # https://pytorch.org/docs/stable/generated/torch.nn.RNN.html?highlight=rnn#torch.nn.RNN
    # 根据官网,torch.nn.RNN接收的参数input形状是[时间步数, 批量大小, 特征维数], hidden: 旧的隐藏层的状态
    def forward(self, input, hidden):
        # output: 隐藏层在各个时间步上计算并输出的隐藏状态, 形状是[时间步数, 批量大小, 隐层维数]
        output, hidden = self.rnn(input, hidden)
        # decoded: 形状是[时间步数, 批量大小, num_skills]
        decoded = self.decoder(output.contiguous().view(output.size(0) * output.size(1), output.size(2)))
        return decoded, hidden

可改进的地方

其他代码与其的不同的地方

可参考文章:DKT学习_qq_40282662的博客-CSDN博客

Deep Knowledge Tracing [Pytorch] | 一切皆可解读 (chsong.live)

torch.optim.Adam(model.parameters(), lr=lr ,eps=args.epsilon)

影响模型效果的因素

学习率,batchsize 一般设置为8的倍数 还有epsilon不要过大 0.01或0.001都可

  • 4
    点赞
  • 35
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
好的,以下是使用 PyTorch 编写知识追踪 DKT-LSTM 模型的完整代码: ```python import torch import torch.nn as nn class DKT_LSTM(nn.Module): def __init__(self, input_dim, hidden_dim, output_dim, num_layers=1, dropout=0.2): super(DKT_LSTM, self).__init__() self.input_dim = input_dim self.hidden_dim = hidden_dim self.output_dim = output_dim self.num_layers = num_layers self.dropout = dropout # 定义 LSTM 层 self.lstm = nn.LSTM(input_dim, hidden_dim, num_layers, batch_first=True, dropout=dropout) # 定义全连接层 self.fc = nn.Linear(hidden_dim, output_dim) # 定义 Dropout 层 self.dropout_layer = nn.Dropout(dropout) def forward(self, x): # LSTM 层的输入形状为 (batch_size, seq_len, input_dim) # 输出形状为 (batch_size, seq_len, hidden_dim) lstm_out, hidden = self.lstm(x) # 取出 LSTM 的最后一个时间步的输出作为全连接层的输入 # 形状为 (batch_size, hidden_dim) last_output = lstm_out[:, -1, :] # Dropout 层 last_output = self.dropout_layer(last_output) # 全连接层 # 输出形状为 (batch_size, output_dim) output = self.fc(last_output) return output ``` 在这个模型中,我们使用了 PyTorch 的 nn.LSTM 类来定义 LSTM 层。我们还使用了 nn.Linear 类来定义全连接层,并使用 nn.Dropout 类来定义 Dropout 层。 在 forward 方法中,我们首先将输入传递给 LSTM 层,然后取出 LSTM 的最后一个时间步的输出,并传递给全连接层。最后,我们使用 Dropout 层对输出进行正则化,并返回输出。 然后,我们可以使用这个模型来训练和预测。例如,我们可以使用以下代码来训练模型: ```python model = DKT_LSTM(input_dim=10, hidden_dim=128, output_dim=2, num_layers=1, dropout=0.2) criterion = nn.CrossEntropyLoss() optimizer = torch.optim.Adam(model.parameters(), lr=0.001) for epoch in range(num_epochs): for i, (inputs, labels) in enumerate(train_loader): optimizer.zero_grad() outputs = model(inputs) loss = criterion(outputs, labels) loss.backward() optimizer.step() if (i+1) % 100 == 0: print('Epoch [{}/{}], Step [{}/{}], Loss: {:.4f}'.format(epoch+1, num_epochs, i+1, len(train_loader), loss.item())) ``` 在这个例子中,我们首先创建了一个 DKT_LSTM 对象,并使用 nn.CrossEntropyLoss 作为损失函数,使用 Adam 优化器进行优化。然后,我们迭代训练数据集,并计算模型的损失,并使用反向传播更新模型的参数。 接下来,我们可以使用以下代码来预测新的数据: ```python with torch.no_grad(): for inputs, _ in test_loader: outputs = model(inputs) _, predicted = torch.max(outputs.data, 1) print(predicted) ``` 在这个例子中,我们首先禁用梯度计算,然后使用模型预测测试数据集的标签,并使用 torch.max 函数找到每个样本中的最大值和索引。最后,我们打印预测的标签。 这就是使用 PyTorch 编写知识追踪 DKT-LSTM 模型的完整代码。当然,具体实现细节将取决于您的具体需求和数据集。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值