#python #deep-learning #neural-network #pytorch
#python #глубокое обучение #нейронная сеть #pytorch
Вопрос:
Я создаю модель для прогнозирования набора данных, и моя точность действительно хороша, но я хотел бы проверить это с помощью отчета о классификации, но я действительно не уверен, как это вписать в мой код. Я изначально не думал об этом, но у меня проблемы. Может кто-нибудь помочь? Обычно, как мы можем сгенерировать отчет о классификации для пользовательской модели?
lb = joblib.load('/content/drive/MyDrive/Colab_Notebooks/outputs/lb.pkl')
class CustomCNN(nn.Module):
def __init__(self):
super(CustomCNN, self).__init__()
self.conv1 = nn.Conv2d(3, 16, 5)
self.conv2 = nn.Conv2d(16, 32, 5)
self.conv3 = nn.Conv2d(32, 64, 3)
self.conv4 = nn.Conv2d(64, 128, 5)
self.fc1 = nn.Linear(128, 256)
self.fc2 = nn.Linear(256, len(lb.classes_))
self.pool = nn.MaxPool2d(2, 2)
def forward(self, x):
x = self.pool(F.relu(self.conv1(x)))
x = self.pool(F.relu(self.conv2(x)))
x = self.pool(F.relu(self.conv3(x)))
x = self.pool(F.relu(self.conv4(x)))
bs, _, _, _ = x.shape
x = F.adaptive_avg_pool2d(x, 1).reshape(bs, -1)
x = F.relu(self.fc1(x))
x = self.fc2(x)
return x
# learning_parameters
lr = 1e-3
batch_size = 32
device = 'cuda' if torch.cuda.is_available() else 'cpu'
print(f"Computation device: {device}n")
# read the data.csv file and get the image paths and labels
df = pd.read_csv('/content/drive/MyDrive/Colab_Notebooks/input/data.csv')
X = df.image_path.values # image paths
y = df.target.values # targets
(xtrain, xtest, ytrain, ytest) = train_test_split(X, y,
test_size=0.10, random_state=42)
print(f"Training instances: {len(xtrain)}")
print(f"Validation instances: {len(xtest)}")
class ImageDataset(Dataset):
def __init__(self, images, labels=None, tfms=None):
self.X = images
self.y = labels
# apply augmentations
if tfms == 0: # if validating
self.aug = albumentations.Compose([
albumentations.Resize(224, 224, always_apply=True),
])
else: # if training
self.aug = albumentations.Compose([
albumentations.Resize(224, 224, always_apply=True),
albumentations.HorizontalFlip(p=0.5),
albumentations.ShiftScaleRotate(
shift_limit=0.3,
scale_limit=0.3,
rotate_limit=15,
p=0.5
),
])
def __len__(self):
return (len(self.X))
def __getitem__(self, i):
image = Image.open(self.X[i])
image = image.convert('RGB')
image = self.aug(image=np.array(image))['image']
image = np.transpose(image, (2, 0, 1)).astype(np.float32)
label = self.y[i]
return (torch.tensor(image, dtype=torch.float), torch.tensor(label, dtype=torch.long))
train_data = ImageDataset(xtrain, ytrain, tfms=1)
test_data = ImageDataset(xtest, ytest, tfms=0)
# dataloaders
trainloader = DataLoader(train_data, batch_size=batch_size, shuffle=True)
testloader = DataLoader(test_data, batch_size=batch_size, shuffle=False)
model = CustomCNN().to(device)
print(model)
# total parameters and trainable parameters
total_params = sum(p.numel() for p in model.parameters())
print(f"{total_params:,} total parameters.")
total_trainable_params = sum(
p.numel() for p in model.parameters() if p.requires_grad)
print(f"{total_trainable_params:,} training parameters.")
# optimizer
optimizer = optim.Adam(model.parameters(), lr=lr)
# loss function
criterion = nn.CrossEntropyLoss()
scheduler = torch.optim.lr_scheduler.ReduceLROnPlateau(
optimizer,
mode='min',
patience=5,
factor=0.5,
min_lr=1e-6,
verbose=True
)
# validation function
def validate(model, test_dataloader):
print('Validating')
model.eval()
val_running_loss = 0.0
val_running_correct = 0
with torch.no_grad():
for i, data in tqdm(enumerate(test_dataloader), total=int(len(test_data) / test_dataloader.batch_size)):
data, target = data[0].to(device), data[1].to(device)
outputs = model(data)
loss = criterion(outputs, target)
val_running_loss = loss.item()
_, preds = torch.max(outputs.data, 1)
val_running_correct = (preds == target).sum().item()
val_loss = val_running_loss / len(test_dataloader.dataset)
val_accuracy = 100. * val_running_correct / len(test_dataloader.dataset)
print(f'Val Loss: {val_loss:.4f}, Val Acc: {val_accuracy:.2f}')
return val_loss, val_accuracy
# training function
def fit(model, train_dataloader):
print('Training')
model.train()
train_running_loss = 0.0
train_running_correct = 0
for i, data in tqdm(enumerate(train_dataloader), total=int(len(train_data) / train_dataloader.batch_size)):
data, target = data[0].to(device), data[1].to(device)
optimizer.zero_grad()
outputs = model(data)
loss = criterion(outputs, target)
train_running_loss = loss.item()
_, preds = torch.max(outputs.data, 1)
train_running_correct = (preds == target).sum().item()
loss.backward()
optimizer.step()
train_loss = train_running_loss / len(train_dataloader.dataset)
train_accuracy = 100. * train_running_correct / len(train_dataloader.dataset)
print(f"Train Loss: {train_loss:.4f}, Train Acc: {train_accuracy:.2f}")
—Я пытался включить сюда отчет о классификации, но да, в моем пользовательском CNN нет отчета о классификации! приведенная ниже часть с комментариями была моей попыткой посмотреть, смогу ли я сгенерировать отчет, но я получаю сообщение об ошибке.
'''
predictions = model.predict(x=xtest.astype("float32"), batch_size=32)
print(classification_report(ytest.argmax(axis=1),
predictions.argmax(axis=1), target_names=lb.classes_))
return train_loss, train_accuracy
'''
train_loss, train_accuracy = [], []
val_loss, val_accuracy = [], []
start = time.time()
for epoch in range(5):
print(f"Epoch {epoch 1} of {epoch 1}")
train_epoch_loss, train_epoch_accuracy = fit(model, trainloader)
val_epoch_loss, val_epoch_accuracy = validate(model, testloader)
train_loss.append(train_epoch_loss)
train_accuracy.append(train_epoch_accuracy)
val_loss.append(val_epoch_loss)
val_accuracy.append(val_epoch_accuracy)
scheduler.step(val_epoch_loss)
end = time.time()
print(f"{(end - start) / 60:.3f} minutes")
##
# accuracy plots
plt.figure(figsize=(10, 7))
plt.plot(train_accuracy, color='green', label='train accuracy')
plt.plot(val_accuracy, color='blue', label='validataion accuracy')
plt.xlabel('Epochs')
plt.ylabel('Accuracy')
plt.legend()
plt.savefig('/content/drive/MyDrive/Colab_Notebooks/outputs/accuracy.png')
plt.show()
# loss plots
plt.figure(figsize=(10, 7))
plt.plot(train_loss, color='orange', label='train loss')
plt.plot(val_loss, color='red', label='validataion loss')
plt.xlabel('Epochs')
plt.ylabel('Loss')
plt.legend()
plt.savefig('/content/drive/MyDrive/Colab_Notebooks/outputs/loss.png')
plt.show()
# serialize the model to disk
print('Saving model...')
torch.save(model.state_dict(), '/content/drive/MyDrive/Colab_Notebooks/outputs/sports.pth')
print('TRAINING COMPLETE')
Ошибка:
--------------------------------------------------------------------------
ModuleAttributeError Traceback (most recent call last)
<ipython-input-5-ad111802746a> in <module>()
157 for epoch in range(5):
158 print(f"Epoch {epoch 1} of {epoch 1}")
--> 159 train_epoch_loss, train_epoch_accuracy = fit(model, trainloader)
160 val_epoch_loss, val_epoch_accuracy = validate(model, testloader)
161 train_loss.append(train_epoch_loss)
1 frames
/usr/local/lib/python3.6/dist-packages/torch/nn/modules/module.py in __getattr__(self, name)
777 return modules[name]
778 raise ModuleAttributeError("'{}' object has no attribute '{}'".format(
--> 779 type(self).__name__, name))
780
781 def __setattr__(self, name: str, value: Union[Tensor, 'Module']) -> None:
ModuleAttributeError: 'CustomCNN' object has no attribute 'predict'
Комментарии:
1. это похоже на pytorch, а не на tensorflow
2. @Nicolas мой плохой, неправильный тег, я это исправил.
3. «predictions = model.predict(x = xtest.astype(«float32″), batch_size = 32)» Закомментирован ли этот раздел?
4. да, потому что я не буду работать, я получаю сообщение об ошибке выше, если я попытаюсь таким образом показать отчет о классификации. В основном это была моя попытка.
Ответ №1:
Я думаю, вы делаете это неправильно в этой строке
predictions = model.predict(x=xtest.astype("float32"), batch_size=32)
Поскольку ваша модель находится в pytorch и наследует nn.module, вам не нужно явно вызывать .predict
для получения прогнозов, потому что они не .predict
работают. .predict
функция доступна в tensorflow keras.
Вы можете просто передать значение в model model(data)
, как в приведенной ниже строке
predictions = []
real_labels = []
for x, y in test_dataloader:
x = x.to(device).float()
out_class = model(x)
label = out_class.cpu().data.numpy().argmax()
predictions.append(label)
real_labels.append(y)
Для вычисления classification_report вы можете сделать следующее
- Установите библиотеку seqeval
pip install seqeval
- Затем выполните следующие действия
from seqeval.metrics import classification_report predictions = [ predictions ] real_labels = [ real_labels ] print(classification_report( predictions, real_labels ))
Убедитесь, что формат predictions
массива и real_labels
список списка подобны [ [ class_1, class_2, ... ] ]
вот почему я добавил extra [ ]
перед переходом в функцию `classification_report’
Он напечатает отчет примерно так, как показано ниже
precision recall f1-score support
ACT 0.00 0.00 0.00 0
CITATION 0.47 0.82 0.60 11
SECTION 0.17 1.00 0.29 1
micro avg 0.38 0.83 0.53 12
macro avg 0.21 0.61 0.30 12
weighted avg 0.45 0.83 0.57 12
где ACT
CITATION
и SECTION
являются классами или метками в моем случае.
Редактировать
Увидев ваш комментарий, я предполагаю, что вы не понимаете, куда следует поместить приведенный выше код, поэтому в вопросе вы прокомментировали некоторые строки
'''
predictions = model.predict(x=xtest.astype("float32"), batch_size=32)
print(classification_report(ytest.argmax(axis=1),
predictions.argmax(axis=1), target_names=lb.classes_))
return train_loss, train_accuracy
'''
Из-за этих строк (после раскомментирования) вы получали ошибку. Потому что вы написали model.predict
.
Просто удалите эти строки и мои строки после всех построений перед этой строкой # serialize the model to disk
Комментарии:
1. Просто небольшая вещь: » вам не нужно явно вызывать .predict для получения прогнозов. » на самом деле
nn.Module
у s нетpredict
функции!2. @coderina итак, приведенный выше код находится за пределами функции def fit или внутри нее?
3. @KSp код выходит за
fit
рамки функции… Я полагаю, вам нужен отчет о классификации после обучения модели … добавьте код, в котором вы пишетеpredictions = model.predict( ....
4. Но проблема в том, что у меня нет модели. предсказать в моем коде. Как вы можете видеть, что также говорит Иван.
5. Нет, нет … в приведенном выше коде вы прокомментировали некоторые строки predictions = model.predict (просто удалите эти строки и добавьте строки, которые я предложил.. Да, в модели pytorch нет функции .predict, есть только функция keras, я уже написал это в своем ответе