Firstly, I am fairly new to python/ML in general. I am attempting to utilize the model depicted at stackabuse over my own data set.
Everything flows smoothly until I get ready to run the epochs.
In debugging I see that it is failing on CrossEntropyLoss function and I get the error expected long found double. The data set it appears to fail on is the my tdiff column that I calculated but I can’t seem to figure out how to convert it to a long.
Is there something that I’m missing in trying to figure this out?
To be clear, this is what I THINK it is based on my extremely limited knowledge on the function:
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()
output:
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 anaconda3libsite-packagestorchnnmodulesmodule.py", line 727, in _call_impl result = self.forward(*input, **kwargs) File anaconda3libsite-packagestorchnnmodulesloss.py", line 961, in forward return F.cross_entropy(input, target, weight=self.weight, File anaconda3libsite-packagestorchnnfunctional.py", line 2468, in cross_entropy return nll_loss(log_softmax(input, 1), target, weight, None, ignore_index, None, reduction) File anaconda3libsite-packagestorchnnfunctional.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
Advertisement
Answer
nn.CrossEntropyLoss()
expects target tensors of type Long
, but what you’re passing is of type Double
.
Try to change this line
from:
single_loss = loss_function(y_pred, train_op)
to:
single_loss = loss_function(y_pred, train_op.long())