Python深度学习(Keras):路透社多类分类

pzfprimi  于 2023-11-19  发布在  Python
关注(0)|答案(1)|浏览(121)

我正在研究这本很棒的书,用PyTorch重写示例,以便更好地保留材料。对于大多数示例,我的结果与书中的Keras代码相当,但我在这个练习中遇到了一些麻烦。对于那些有书的人,这是在第106页。
书中用于对文本进行分类的网络如下:

图书代码(Keras)

keras_model = keras.Sequential([
    layers.Dense(64,activation='relu'),
    layers.Dense(64,activation='relu'),
    layers.Dense(46,activation='softmax'),
])

keras_model.compile(
    optimizer = 'rmsprop',
    loss = 'sparse_categorical_crossentropy',
    metrics = ['accuracy']
)

hist = keras_model.fit(
    partial_train_xs,
    partial_train_ys,
    epochs=20,
    batch_size=512,
    validation_data=[val_xs,val_ys]
)

字符串

我尝试在PyTorch中重新创建相同的内容:

model = nn.Sequential(
          nn.Linear(10_000,64),
          nn.ReLU(),
          nn.Linear(64,64),
          nn.ReLU(),
          nn.Linear(64,46),
          nn.Softmax()
        )

def compute_val_loss(model,xs,ys):
    preds = model(xs)
    return(F.cross_entropy(preds,ys)).item()

def compute_accuracy(model,xs,ys):
    preds = model(xs)
    acc = (preds.argmax(dim=1) == ys).sum() / len(preds)
    return acc.item()

def train_loop(model,xs,ys,epochs=20,lr=1e-3,opt=torch.optim.RMSprop,
               batch_size=512,loss_func=F.cross_entropy):
    opt = opt(model.parameters(),lr=lr)
    losses = []
    for i in range(epochs):
        epoch_loss = []
        for b in range(0,len(xs),batch_size):
            xbatch = xs[b:b+batch_size]
            ybatch = ys[b:b+batch_size]            
            logits = model(xbatch)
            loss = loss_func(logits,ybatch)
            model.zero_grad()
            loss.backward()
            opt.step()
            epoch_loss.append(loss.item())
        losses.append([i,sum(epoch_loss)/len(epoch_loss)])
        print(loss.item())
    return losses


为了简洁,我已经排除了数据加载部分,但它只是对单词序列进行“多点”编码。例如,如果vocab是10 k单词,则每个输入都是一个10 k向量,其中向量中的每个索引都对应于vocab中的单词索引。

我的问题:

我在这里遇到的问题是,这本书的Keras版本之间的结果存在很大差异(其行为符合预期)和PyTorch版本。经过20个epoch,Keras版本的训练损失可以忽略不计,约为80%。在有效期上是准确的。然而,Torch版本几乎没有在训练损失上移动。对于上下文,它从大约3.4开始,在20个epoch后结束,3.1. Keras版本的火车损失比单个纪元后的火车损失更低(2.6)。
Torch 版本在准确性上确实取得了进步,尽管仍然落后于Keras版本。准确性也有一个奇怪的阶梯模式:
x1c 0d1x的数据
我在Torch版本中做错了什么?或者有一个合理的理由来解释预期的分歧?两个库的RMSProp args中有一些微小的超参数差异,但我摆弄了一下,并没有看到太大的差异。两者的学习率是相等的。即使我运行 Torch 版本150个epoch,训练/测试损失继续下降(非常缓慢),但验证准确度在75%左右达到峰值。

63lcw9qa

63lcw9qa1#

经过更多的研究(和睡眠),我发现损失函数(交叉熵)在PyTorch中期望原始logits,而在Keras中它期望概率。您可以在Keras版本中设置from_logits = True以使它们等效。
在PyTorch版本中删除Softmax层,我得到了大致相同的结果。

相关问题