Я тренирую модель Wave Vision Transformer. Код Wave_ViT доступен по ссылке ниже. https://github.com/YehLi/ImageNetModel/ ... wavevit.py
Я не менял код файлов wave_ViT.py и torch_wavelets.py. Единственное изменение, которое я внес, касается способа предоставления данных для модели. Мой исходный набор данных включает около 38 000 изображений МРТ, из них 256 в формате RGB. Я дополнил этот набор данных, повернув каждое изображение от исходного угла на 90, 180, 270 градусов, и сохранил эти изображения. Таким образом, каждое изображение имеет три повернутые копии. Следовательно, мой исходный набор данных увеличился примерно до 156 000 изображений того же размера и формата.
Я сохранил эти изображения с метками в формате numpy.memmap uint8, поскольку мой код выдавал ошибку OOM. при попытке сразу загрузить их в массив numpy.
Я загружаю свою карту памяти в поезде и тестирую изображения с такими метками.
Мой класс тренера выглядит так. Это берет изображения и метки, дополняет их конкретным преобразованием для эпохи, а затем обучает и тестирует их на модели.
Epoch: 1
Training Metrics: Accuracy: 0.7357, Loss: 0.5236, Precision: 0.6928, Recall: 0.8479, F1 Score: 0.7625
Testing Metrics: Accuracy: 0.7672, Loss: 0.4838, Precision: 0.7271, Recall: 0.8556, F1 Score: 0.7861
....
Epoch: 4
Training Metrics: Accuracy: 0.8031, Loss: 0.4078, Precision: 0.7644, Recall: 0.8772, F1 Score: 0.8169
Testing Metrics: Accuracy: 0.7494, Loss: 0.4712, Precision: 0.8186, Recall: 0.6408, F1 Score: 0.7189
...
Epoch: 8
Training Metrics: Accuracy: 0.8529, Loss: 0.3148, Precision: 0.8324, Recall: 0.8845, F1 Score: 0.8577
Testing Metrics: Accuracy: 0.8280, Loss: 0.4027, Precision: 0.8015, Recall: 0.8720, F1 Score: 0.8352
...
Epoch: 18
Training Metrics: Accuracy: 0.9284, Loss: 0.1706, Precision: 0.9237, Recall: 0.9346, F1 Score: 0.9292
Testing Metrics: Accuracy: 0.8008, Loss: 0.5767, Precision: 0.8357, Recall: 0.7488, F1 Score: 0.7899
The model does not over give me the best accuracy and loss at epoch. I have saved the mode at epoch 8 and then keep its accuracy and loss between 79-80.
Эта модель при проверке на независимом наборе данных показала плохие результаты.
Я также проверил его на том же наборе данных, что и при обучении, и точность осталась прежней (хотя я предоставил ему те же изображения, которые использовал при обучении). Я использовал предварительно обученные веса ImageNet (исходный WaveViT был обучен на ImageNet, а сохраненная модель присутствует на GitHub) и для этого WaveViT, но результат тот же.
Пожалуйста, это будет большим подспорьем, если кто-нибудь поможет мне разобраться с таким поведением модели.
Почему точность проверки даже на том же наборе данных, который использовался для обучения и тестирования, не улучшилась?
Надеюсь, я все объяснил. Если вам нужны дополнительные разъяснения, дайте мне знать.
Спасибо
Я тренирую модель Wave Vision Transformer. Код Wave_ViT доступен по ссылке ниже. https://github.com/YehLi/ImageNetModel/blob/main/classification/wavevit.py Я не менял код файлов wave_ViT.py и torch_wavelets.py. Единственное изменение, которое я внес, касается способа предоставления данных для модели. Мой исходный набор данных включает около 38 000 изображений МРТ, из них 256 в формате RGB. Я дополнил этот набор данных, повернув каждое изображение от исходного угла на 90, 180, 270 градусов, и сохранил эти изображения. Таким образом, каждое изображение имеет три повернутые копии. Следовательно, мой исходный набор данных увеличился примерно до 156 000 изображений того же размера и формата. Я сохранил эти изображения с метками в формате numpy.memmap uint8, поскольку мой код выдавал ошибку OOM. при попытке сразу загрузить их в массив numpy. Я загружаю свою карту памяти в поезде и тестирую изображения с такими метками. [code]def load_memmap_data( train_memmap_file, train_label_memmap_file, test_memmap_file, test_label_memmap_file,num_train_images, num_test_images): train_images = np.memmap(train_memmap_file, dtype='uint8', mode='r', shape=(num_train_images, 256, 256, 3)) train_labels = np.memmap(train_label_memmap_file, dtype='int32', mode='r', shape=(num_train_images,))
train_images, train_labels, test_images, test_labels = load_memmap_data( train_memmap_file=train_memmap_file, train_label_memmap_file=train_label_memmap_file, test_memmap_file=test_memmap_file, test_label_memmap_file=test_label_memmap_file, num_train_images=num_train_images, num_test_images=num_test_images ) [/code] Мой оптимизатор и вызов функции обучения в классе Trainer выглядят так. [code]model = WaveViT() model = nn.DataParallel(model)
optimizer = optim.AdamW(model.parameters(), lr=1e-4, weight_decay=1e-4) loss_fn = nn.CrossEntropyLoss() trainer = Trainer(model, optimizer, loss_fn, exp_name="waveViT-256-aug", device=device) trainer.train(train_images, train_labels, test_images, test_labels, epochs=100, config=None, steps_per_epoch=steps_per_epoch, augment=False) [/code] Мой класс тренера выглядит так. Это берет изображения и метки, дополняет их конкретным преобразованием для эпохи, а затем обучает и тестирует их на модели. [code]class Trainer: def __init__(self, model, optimizer, loss_fn, exp_name, device): self.model = model.to(device) self.optimizer = optimizer self.loss_fn = loss_fn self.exp_name = exp_name self.device = device def train(self, train_images, train_labels, test_images, test_labels, epochs, config = None,steps_per_epoch = 0,augment = False): train_losses, test_losses, test_accuracies,train_accuracies,test_precision,train_precision,test_recall,train_recall,test_f1,train_f1 = [], [], [],[],[],[],[],[],[],[] best_test_loss = float('inf') # Initialize with a large value best_accuracy = 0.0 # Initialize with the worst possible accuracy scaler = GradScaler() # Early stopping variables best_epoch = 0 epochs_no_improvement = 0 # Counter for epochs without improvement # Train the model transform_1 = transforms.Compose([ # Rotate the image by 0-40 degrees transforms.RandomAffine(degrees=(-40,40), shear=15), transforms.RandomVerticalFlip(p=0.5), transforms.ToTensor(),])
transform_2 = transforms.Compose([ # Shear with a 20-degree angle transforms.RandomResizedCrop(size=224, scale=(0.95, 1.0)), transforms.RandomVerticalFlip(p=0.5), transforms.RandomAffine(degrees=0, translate=(0.15, 0.15)), transforms.RandomApply([transforms.ElasticTransform(alpha=30.0)], p=0.3),transforms.ToTensor(),])
transform_3 = transforms.Compose([transforms.ToTensor(),]) for i in range(epochs): print("\nTraining epoch\n") print("Preparing data loaders...") if i % 2 == 0: transform = transform_1 elif i % 2 == 0 and i % 7 == 0: transform = transform_3# If divisible by 2 else: transform = transform_2 # Otherwise trainloader, testloader = prepare_data(
if is_best_accuracy:# Update best test loss best_accuracy = max(accuracy_test, best_accuracy) # Update best accuracy save_checkpoint(self.exp_name + "-Best-Test-Accuracy", self.model, i+1)
if epochs_no_improvement >= 10: print(f"Early stopping triggered after {i + 1} epochs without improvement.") break # Stop training if no improvement
def train_epoch(self, trainloader, steps_per_epoch, augment,scaler): self.model.train() total_loss = 0 trainloader_iter = itertools.cycle(trainloader) correct = 0 y_true = [] y_pred = [] # To store all true labels # Wrap the range with tqdm for the progress bar with tqdm(total=steps_per_epoch, desc='Training', unit='step') as pbar: for i in range(steps_per_epoch): batch = next(trainloader_iter) batch = [t.to(self.device) for t in batch] images, labels = batch images, labels = images.to(self.device), labels.to(self.device)
images = images.to(torch.float32) with autocast(): result = self.model(images) loss = self.loss_fn(result, labels) self.optimizer.zero_grad()
scaler.scale(loss).backward() # Update the model's parameters scaler.step(self.optimizer) scaler.update()
total_loss += loss.item() * len(images) predictions = torch.argmax(result, dim=1) y_pred.extend(predictions.cpu().numpy()) y_true.extend(labels.cpu().numpy()) correct += torch.sum(predictions == labels).item() # Update the progress bar only after 25% of the progress is done if (i + 1) % (steps_per_epoch // 4) == 0: # 25% of total steps pbar.update(1)
# Convert lists to tensors for calculation y_true_tensor = torch.tensor(y_true) y_pred_tensor = torch.tensor(y_pred)
u/torch.no_grad() def evaluate(self, testloader): self.model.eval() total_loss = 0 correct = 0 y_true = [] y_pred = [] with torch.no_grad(): for batch in testloader: # Move the batch to the device batch = [t.to(self.device) for t in batch] images, labels = batch images = images.to(torch.float32) with autocast(): result = self.model(images) loss = self.loss_fn(result, labels)
precision = TP / (TP + FP) if TP + FP > 0 else 0 recall = TP / (TP + FN) if TP + FN > 0 else 0 f1 = 2 * (precision * recall) / (precision + recall) if (precision + recall) > 0 else 0 accuracy = correct / len(testloader.dataset) avg_loss = total_loss / len(testloader.dataset) return accuracy, avg_loss,precision,recall,f1 [/code] Модель работает очень хорошо при обучении и тестировании на одном и том же наборе данных. [code]Epoch: 1 Training Metrics: Accuracy: 0.7357, Loss: 0.5236, Precision: 0.6928, Recall: 0.8479, F1 Score: 0.7625 Testing Metrics: Accuracy: 0.7672, Loss: 0.4838, Precision: 0.7271, Recall: 0.8556, F1 Score: 0.7861 .... Epoch: 4 Training Metrics: Accuracy: 0.8031, Loss: 0.4078, Precision: 0.7644, Recall: 0.8772, F1 Score: 0.8169 Testing Metrics: Accuracy: 0.7494, Loss: 0.4712, Precision: 0.8186, Recall: 0.6408, F1 Score: 0.7189 ... Epoch: 8 Training Metrics: Accuracy: 0.8529, Loss: 0.3148, Precision: 0.8324, Recall: 0.8845, F1 Score: 0.8577 Testing Metrics: Accuracy: 0.8280, Loss: 0.4027, Precision: 0.8015, Recall: 0.8720, F1 Score: 0.8352 ... Epoch: 18 Training Metrics: Accuracy: 0.9284, Loss: 0.1706, Precision: 0.9237, Recall: 0.9346, F1 Score: 0.9292 Testing Metrics: Accuracy: 0.8008, Loss: 0.5767, Precision: 0.8357, Recall: 0.7488, F1 Score: 0.7899 The model does not over give me the best accuracy and loss at epoch. I have saved the mode at epoch 8 and then keep its accuracy and loss between 79-80.
[/code] Эта модель при проверке на независимом наборе данных показала плохие результаты. [code]Validation Metrics: - Accuracy: 0.4890 - Precision: 0.4878 - Recall: 0.4416 - F1 Score: 0.4636 - Confusion Matrix: [[1341 1159] [1396 1104]] [/code] Я также проверил его на том же наборе данных, что и при обучении, и точность осталась прежней (хотя я предоставил ему те же изображения, которые использовал при обучении). Я использовал предварительно обученные веса ImageNet (исходный WaveViT был обучен на ImageNet, а сохраненная модель присутствует на GitHub) и для этого WaveViT, но результат тот же. Пожалуйста, это будет большим подспорьем, если кто-нибудь поможет мне разобраться с таким поведением модели. Почему точность проверки даже на том же наборе данных, который использовался для обучения и тестирования, не улучшилась? Надеюсь, я все объяснил. Если вам нужны дополнительные разъяснения, дайте мне знать. Спасибо
Я тренирую модель Wave Vision Transformer. Код Wave_ViT доступен по ссылке ниже.
Я не менял код файлов wave_ViT.py и torch_wavelets.py. Единственное изменение, которое я внес, касается способа предоставления данных для модели. Мой исходный набор...
I have just started doing Vision Transformer from scratch using pytorch. And the I got error like this when I run the training helper code. I know it is about the shape is not match, but I don't know which one I should do. The code is like this :...
Я реализую модель Vision Transformer в рамках школьного проекта, и мне нужно построить карту внимания, чтобы сравнить различия между моделью CNN и моделью ViT, но я не знаю, как это сделать.
Для справки: я использовал код в этом блокноте, за...
Я работаю с моделью Vision Transformer (ViT), используя PyTorch и библиотеку timm. Моя цель — изменить модель ViT, чтобы заменить заголовок классификации по умолчанию пользовательским заголовком, который принимает среднее значение всех токенов и...
Я работаю с моделью Vision Transformer (ViT), используя PyTorch и библиотеку timm. Моя цель — изменить модель ViT, чтобы заменить заголовок классификации по умолчанию пользовательским заголовком, который принимает среднее значение всех токенов и...