Skip to content

RuntimeError: One of the differentiated Tensors appears to not have been used in the graph. Set allow_unused=True if this is the desired behavior. #1571

@quanxing

Description

@quanxing

❓ Questions and Help

import torch
import torch.nn as nn
import pandas as pd
from sklearn.preprocessing import LabelEncoder, StandardScaler
from sklearn.model_selection import train_test_split

class TitanicDNNModel(nn.Module):
def init(self, num_sex, num_embarked, num_pclass, embedding_dim=4):
super(TitanicDNNModel, self).init()

    # Embedding layers
    self.sex_embedding = nn.Embedding(num_sex, embedding_dim)
    self.embarked_embedding = nn.Embedding(num_embarked, embedding_dim)
    self.pclass_embedding = nn.Embedding(num_pclass, embedding_dim)
    
    # FC layers
    self.fc_input_dim = embedding_dim * 3 + 3  # 3 embedded features + 3 numerical
    
    self.fc1 = nn.Linear(self.fc_input_dim, 64)
    self.relu1 = nn.ReLU()
    self.fc2 = nn.Linear(64, 32)
    self.relu2 = nn.ReLU()
    self.fc3 = nn.Linear(32, 2)  # Output logits for 2 classes
    self.softmax = nn.Softmax(dim=1)
    
def forward(self, sex, embarked, pclass, age, parch, fare):
    # Embed categorical features
    sex_emb = self.sex_embedding(sex.long()).view(sex.size(0), -1)
    embarked_emb = self.embarked_embedding(embarked.long()).view(embarked.size(0), -1)
    pclass_emb = self.pclass_embedding(pclass.long()).view(pclass.size(0), -1)
    
    # Concatenate all features
    x = torch.cat([
        sex_emb,
        embarked_emb,
        pclass_emb,
        age.unsqueeze(1),
        parch.unsqueeze(1),
        fare.unsqueeze(1)
    ], dim=1)
    
    # Forward pass
    x = self.relu1(self.fc1(x))
    x = self.relu2(self.fc2(x))
    return self.softmax(self.fc3(x))  # Return logits

Load and preprocess data

train_df = pd.read_csv("/data/usershare/work/code/FuxiCTR/data/tiny_csv/titanic_train.csv")
features = ['sex', 'embarked', 'pclass', 'age', 'parch', 'fare']
X = train_df[features]
y = train_df['survived']

Encode categorical features

le = LabelEncoder()
X['sex'] = le.fit_transform(X['sex'].fillna('missing'))
X['embarked'] = le.fit_transform(X['embarked'].fillna('missing'))
X['pclass'] = le.fit_transform(X['pclass'].fillna('missing'))

Scale numerical features

scaler = StandardScaler()
num_features = ['age', 'parch', 'fare']
X[num_features] = scaler.fit_transform(X[num_features].fillna(0))

X = X.astype(float)

Split data

X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)

Convert to tensors

def df_to_tensors(df):
return (
torch.tensor(df['sex'].values),
torch.tensor(df['embarked'].values),
torch.tensor(df['pclass'].values, dtype=torch.long),
torch.tensor(df['age'].values, dtype=torch.float32),
torch.tensor(df['parch'].values, dtype=torch.float32),
torch.tensor(df['fare'].values, dtype=torch.float32)
)

X_train_tensors = df_to_tensors(X_train)
X_test_tensors = df_to_tensors(X_test)
y_train_tensor = torch.tensor(y_train.values, dtype=torch.long)
y_test_tensor = torch.tensor(y_test.values, dtype=torch.long)

Initialize model, loss, optimizer

model = TitanicDNNModel(
num_sex=X['sex'].nunique(),
num_embarked=X['embarked'].nunique(),
num_pclass=X['pclass'].nunique()
)
criterion = nn.CrossEntropyLoss()
optimizer = torch.optim.Adam(model.parameters(), lr=0.001)

Training loop

epochs = 100
for epoch in range(epochs):
model.train()
optimizer.zero_grad()

outputs = model(*X_train_tensors)
loss = criterion(outputs, y_train_tensor)
loss.backward()
optimizer.step()

if (epoch + 1) % 10 == 0:
    with torch.no_grad():
        model.eval()
        test_outputs = model(*X_test_tensors)
        test_loss = criterion(test_outputs, y_test_tensor)
        _, predicted = torch.max(test_outputs, 1)
        correct = (predicted == y_test_tensor).sum().item()
        accuracy = correct / len(y_test_tensor)
        
        print(f"Epoch [{epoch+1}/{epochs}], "
              f"Train Loss: {loss.item():.4f}, "
              f"Test Loss: {test_loss.item():.4f}, "
              f"Test Acc: {accuracy:.4f}")

from captum.attr import IntegratedGradients
import matplotlib.pyplot as plt
import numpy as np

使用测试集的一个batch进行分析

batch_size = 32
test_indices = torch.randperm(len(X_test_tensors[0]))[:batch_size]
batch_data = [tensor[test_indices] for tensor in X_test_tensors]

def model_forward(sex, embarked, pclass, age, parch, fare):
# 将类别变量从 float 转回 long
sex = sex.long()
embarked = embarked.long()
pclass = pclass.long()

# 数值变量保持 float
age = age.float()
parch = parch.float()
fare = fare.float()

# 调用模型
logits = model(sex, embarked, pclass, age, parch, fare)
return logits

初始化 IntegratedGradients

ig = IntegratedGradients(model_forward)

准备输入数据(确保是 float 类型)

batch_data = [t.float().requires_grad_() for t in batch_data]

计算归因

attr_ig, delta = ig.attribute(
inputs=tuple(batch_data),
target=1,
return_convergence_delta=True
)
how to fix this problem? thanks

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions