Python错误RuntimeError:标量类型应为Long,但找到Double

2024-04-25 22:56:42 发布

您现在位置:Python中文网/ 问答频道 /正文

首先,一般来说,我对python/ML是相当陌生的。我试图在我自己的数据集上使用stackabuse中描述的模型

一切都进展顺利,直到我准备好迎接新纪元

在调试过程中,我看到它在CrossEntropyLoss函数上失败,我得到了预期的错误long found double。它似乎失败的数据集是我计算的my tdiff列,但我似乎不知道如何将其转换为long

我在试图弄清楚这件事的过程中有没有遗漏什么

明确地说,我认为这是基于我对该功能极其有限的知识:

import pandas as pd
import sqlite3 as sq
import numpy as np 
import torch
import torch.nn as nn
import matplotlib.pyplot as plt
import seaborn as sns 






con = sq.connect("filepath")
df = pd.read_sql_query("SELECT b.actcod," +
         "a.trnqty, " +
          "b.dlytrn_id, " +
              "a.usr_id, " +
 " b.oprcod, " +
 "b.usr_id as usrid," +
 " b.tostol as frstol," +
 " a.tostol, " +
 " b.trndte as bdte," +
 " a.trndte as adte," +
 " '' as tdiff" +
 " FROM" +
 " (SELECT  row_number() over(PARTITION by usr_id order by trndte) AS rown," +
 " trndte," +
 " dlytrn_id," +
 " trnqty, " +
 " oprcod," +
 " actcod," +
 " frstol," +
 " tostol," +
 " usr_id" +
 " FROM Master_File" +
 " WHERE actcod = 'PALPCK') a " +
 " JOIN "+
 " (SELECT  row_number() over(PARTITION by usr_id order by trndte) AS rown," +
 " trndte,dlytrn_id, trnqty, oprcod,actcod, frstol, tostol, usr_id" +
 " FROM Master_File" +
 " WHERE actcod = 'PALPCK' ) b" +
 " ON b.rown = (a.rown -1)" +
 " and b.usr_id = a.usr_id" #+
 #" LIMIT 10"
,con)


# Create record Count
record_count = df['dlytrn_id'].count()
test_records = int(record_count * .2)
print(record_count)
print(test_records)

#Calculate time delta between scans

df['tdiff'] = pd.TimedeltaIndex.total_seconds(pd.to_datetime(df['adte'].values) - pd.to_datetime(df['bdte'].values))



# Establish column types

cat_column = ['usrid','actcod','tostol','frstol']
num_column = ['trnqty']
dte_column = ['bdte','adte']
op_column = ['tdiff']




#convert column datatypes
for category in cat_column:
    df[category] = df[category].astype('category')
for category in num_column:
    df[category] = df[category].astype('float64')
for category in dte_column:
    df[category] = df[category].astype('datetime64')   
    


#create categorical tensor

usr = df['usrid'].cat.codes.values
act = df['actcod'].cat.codes.values
to = df['tostol'].cat.codes.values
fr = df['frstol'].cat.codes.values

cat_data = np.stack([usr,act,to,fr], 1)
cat_data = torch.tensor(cat_data, dtype=torch.int64)

#Create Numerical Tensor

num_data = np.stack([df[col].values for col in num_column], 1)
num_data = torch.tensor(num_data, dtype=torch.float)



#convert output array

op_data = torch.tensor(df[op_column].values).flatten()

print(df.shape)
print(cat_data.shape)
print(num_data.shape)
print(op_data.shape)


#convert categorical data into an N-Dimensional vector,
#this will allow better ML analysis on relationships

cat_col_sizes = [len(df[column].cat.categories) for column in cat_column]
cat_embedding_sizes = [(col_size, min(50, (col_size+1)//2)) for col_size in cat_col_sizes]
print(cat_embedding_sizes)

#create test batches



cat_train_data = cat_data[:record_count-test_records]
cat_test_data = cat_data[record_count-test_records:record_count]
num_train_data = num_data[:record_count-test_records]
num_test_data = num_data[record_count-test_records:record_count]
train_op = op_data[:record_count-test_records]
test_op = op_data[record_count-test_records:record_count]


print(len(cat_train_data))
print(len(num_train_data))
print(len(train_op))

print(len(cat_test_data))
print(len(num_test_data))
print(len(test_op))



class Model(nn.Module):

    def __init__(self, embedding_size, num_numerical_cols, output_size, layers, p=0.4):
        super().__init__()
        self.all_embeddings = nn.ModuleList([nn.Embedding(ni, nf) for ni, nf in embedding_size])
        self.embedding_dropout = nn.Dropout(p)
        self.batch_norm_num = nn.BatchNorm1d(num_numerical_cols)

        all_layers = []
        num_categorical_cols = sum((nf for ni, nf in embedding_size))
        input_size = num_categorical_cols + num_numerical_cols

        for i in layers:
            all_layers.append(nn.Linear(input_size, i))
            all_layers.append(nn.ReLU(inplace=True))
            all_layers.append(nn.BatchNorm1d(i))
            all_layers.append(nn.Dropout(p))
            input_size = i

        all_layers.append(nn.Linear(layers[-1], output_size))

        self.layers = nn.Sequential(*all_layers)

    def forward(self, x_categorical, x_numerical):
        embeddings = []
        for i,e in enumerate(self.all_embeddings):
            embeddings.append(e(x_categorical[:,i]))
        x = torch.cat(embeddings, 1)
        x = self.embedding_dropout(x)

        x_numerical = self.batch_norm_num(x_numerical)
        x = torch.cat([x, x_numerical], 1)
        x = self.layers(x)
        return x
    
    
model = Model(cat_embedding_sizes, num_data.shape[1], 1, [200,100,50], p=0.4)
print(model)

loss_function = nn.CrossEntropyLoss()

optimizer = torch.optim.Adam(model.parameters(), lr=0.001)

epochs = 300
aggregated_losses = []

for i in range(epochs):
    i += 1
    y_pred = model(cat_train_data, num_train_data)
    single_loss = loss_function(y_pred, train_op)
    aggregated_losses.append(single_loss)

    if i%25 == 1:
        print(f'epoch: {i:3} loss: {single_loss.item():10.8f}')

    optimizer.zero_grad()
    single_loss.backward()
    optimizer.step()

print(f'epoch: {i:3} loss: {single_loss.item():10.10f}')

print(train_op)
print(type(train_op))

print(op_column)
print(type(op_column))

print(op_data)
print(type(op_data))


con.close()

输出:

51779
10355
(51779, 11)
torch.Size([51779, 4])
torch.Size([51779, 1])
torch.Size([51779])
[(185, 50), (1, 1), (302, 50), (303, 50)]
41424
41424
41424
10355
10355
10355
Model(
  (all_embeddings): ModuleList(
    (0): Embedding(185, 50)
    (1): Embedding(1, 1)
    (2): Embedding(302, 50)
    (3): Embedding(303, 50)
  )
  (embedding_dropout): Dropout(p=0.4, inplace=False)
  (batch_norm_num): BatchNorm1d(1, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
  (layers): Sequential(
    (0): Linear(in_features=152, out_features=200, bias=True)
    (1): ReLU(inplace=True)
    (2): BatchNorm1d(200, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
    (3): Dropout(p=0.4, inplace=False)
    (4): Linear(in_features=200, out_features=100, bias=True)
    (5): ReLU(inplace=True)
    (6): BatchNorm1d(100, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
    (7): Dropout(p=0.4, inplace=False)
    (8): Linear(in_features=100, out_features=50, bias=True)
    (9): ReLU(inplace=True)
    (10): BatchNorm1d(50, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
    (11): Dropout(p=0.4, inplace=False)
    (12): Linear(in_features=50, out_features=1, bias=True)
  )
)
Traceback (most recent call last):

  File  line 193, in <module>
    single_loss = loss_function(y_pred, train_op)

  File anaconda3\lib\site-packages\torch\nn\modules\module.py", line 727, in _call_impl
    result = self.forward(*input, **kwargs)

  File anaconda3\lib\site-packages\torch\nn\modules\loss.py", line 961, in forward
    return F.cross_entropy(input, target, weight=self.weight,

  File anaconda3\lib\site-packages\torch\nn\functional.py", line 2468, in cross_entropy
    return nll_loss(log_softmax(input, 1), target, weight, None, ignore_index, None, reduction)

  File anaconda3\lib\site-packages\torch\nn\functional.py", line 2264, in nll_loss
    ret = torch._C._nn.nll_loss(input, target, weight, _Reduction.get_enum(reduction), ignore_index)

RuntimeError: expected scalar type Long but found Double

Tags: intesttruedfdatacountcolumnnn
1条回答
网友
1楼 · 发布于 2024-04-25 22:56:42

nn.CrossEntropyLoss()需要类型为Long的目标张量,但您传递的是类型为Double

试着改变这一行

发件人: single_loss = loss_function(y_pred, train_op)

致: single_loss = loss_function(y_pred, train_op.long())

相关问题 更多 >