Я не знаю, почему в этой ситуации я получаю сообщение «Произошло исключение»

Я пытаюсь запустить код из https://github.com/DDI-Dataset/DDI-Code с его набором данных (уже скачан и добавлен в папку, как указано автором), и получаю сообщение «Произошло исключение: Исключение. Посетите https://stanfordaimi.azurewebsites.net/datasets/35866158-8196-48d8-87bf-50dca81df965, чтобы загрузить набор данных DDI». при использовании отладчика Python в VScode.

Ниже приведен код из файла ddi_dataset.py.

"""Code for loading DDI Dataset."""

from torch.utils.data import Subset
from torchvision.datasets import ImageFolder
from torchvision import transforms as T
import os
import pandas as pd
import numpy as np

means = [0.485, 0.456, 0.406]
stds  = [0.229, 0.224, 0.225]
test_transform = T.Compose([
    lambda x: x.convert('RGB'),
    T.Resize(299),
    T.CenterCrop(299),
    T.ToTensor(),
    T.Normalize(mean=means, std=stds)
])

class DDI_Dataset(ImageFolder):
    _DDI_download_link = "https://stanfordaimi.azurewebsites.net/datasets/35866158-8196-48d8-87bf-50dca81df965"
    """DDI Dataset.

    Args:
        root     (str): Root directory of dataset.
        csv_path (str): Path to the metadata CSV file. Defaults to `{root}/ddi_metadata.csv`
        transform     : Function to transform and collate image input. (can use test_transform from this file) 
    """ 
   # root = 'C:\\Users\\User\\OneDrive\\desktop\\CSproject\\datasets\\DDI\\images'
    def __init__(self, root, csv_path=None, download=True, transform=None, *args, **kwargs):
        if csv_path is None:
            csv_path = os.path.join(root, "ddi_metadata.csv")
        if not os.path.exists(csv_path) and download:
            raise Exception(f"Please visit <{DDI_Dataset._DDI_download_link}> to download the DDI dataset.")
        assert os.path.exists(csv_path), f"Path not found <{csv_path}>."
        super(DDI_Dataset, self).__init__(root, *args, transform=transform, **kwargs)
        self.annotations = pd.read_csv(csv_path)
        m_key = 'malignant'
        if m_key not in self.annotations:
            self.annotations[m_key] = self.annotations['malignancy(malig=1)'].apply(lambda x: x==1)

    def __getitem__(self, index):
        img, target = super(DDI_Dataset, self).__getitem__(index)
        path = self.imgs[index][0]        
        annotation = dict(self.annotations[self.annotations.DDI_file==path.split("/")[-1]])
        target = int(annotation['malignant'].item()) # 1 if malignant, 0 if benign
        skin_tone = annotation['skin_tone'].item() # Fitzpatrick- 12, 34, or 56
        return path, img, target, skin_tone

    """Return a subset of the DDI dataset based on skin tones and malignancy of lesion.

    Args:
        skin_tone    (list of int): Which skin tones to include in the subset. Options are {12, 34, 56}.
        diagnosis    (list of str): Include malignant and/or benign images. Options are {"benign", "malignant"}
    """
    def subset(self, skin_tone=None, diagnosis=None):
        skin_tone = [12, 34, 56] if skin_tone is None else skin_tone
        diagnosis = ["benign", "malignant"] if diagnosis is None else diagnosis
        for si in skin_tone: 
            assert si in [12,34,56], f"{si} is not a valid skin tone"
        for di in diagnosis: 
            assert di in ["benign", "malignant"], f"{di} is not a valid diagnosis"
        indices = np.where(self.annotations['skin_tone'].isin(skin_tone) & \
                           self.annotations['malignant'].isin([di= = "malignant" for di in diagnosis]))[0]
        return Subset(self, indices)

Я подумал, что проблема в том, что переменная root не содержит пути к файлу, поэтому я попытался добавить к ней абсолютный путь к файлу (комментарий выше, root = 'C:\\Users\\User\\OneDrive\\desktop\\CSproject\\datasets\\DDI\\images'); однако появилось то же сообщение об ошибке.

Ниже указано расположение файла на моем компьютере.

ddi_dataset.py: C:\Users\User\OneDrive\desktop\CSproject\dataset\DDI\ddi_dataset.py

Изображений: C:\Users\User\OneDrive\desktop\CSproject\dataset\DDI\images («images» — это папка, в которую я поместил PNG: и ddi_metadata.csv)

Кроме того, ниже приведен код из eval_ddi.py, где он вызывает DDI_Dataset.

"""
Code to evaluate the models trained for our paper, 
    "Disparities in Dermatology AI Performance on a Diverse, 
     Curated Clinical Image Set",
on the DDI dataset. 

Note: assumes DDI data is organized as
    ./DDI
        /images
            /000001.png
            /000002.png
            ...
        /ddi_metadata.csv

(After downloading from the Stanford AIMI repository, this requires moving all .png files into a new subdirectory titled "images".)

------------------------------------------------------
Examples:

(1) w/command line interface
# evaluate DeepDerm on DDI and store results in `DDI-results`
>>>python3 eval_ddi.py --model=DeepDerm --data_dir=DDI --eval_dir=DDI-results 

(2) w/python functions
>>>import eval_ddi
>>>import ddi_model
>>>model = ddi_model.load_model("DeepDerm") # load DeepDerm model
>>>eval_results = eval_ddi.eval_model(model, "DDI") # evaluate images in DDI folder
"""

import argparse
from ddi_dataset import DDI_Dataset, test_transform
from ddi_model import load_model
import matplotlib.pyplot as plt
import numpy as np
import os
import pickle
from sklearn.metrics import (f1_score, balanced_accuracy_score, 
    classification_report, confusion_matrix, roc_curve, auc)
import torch
import tqdm


def get_args():
    parser = argparse.ArgumentParser()
    parser.add_argument('--model_dir', type=str, default = "DDI-models", 
        help = "File path for where to save models.")
    parser.add_argument('--model', type=str, default = "DeepDerm", 
        help = "Name of the model to load (HAM10000, DeepDerm, GroupDRO, CORAL,"\
             " or CDANN).")
    parser.add_argument('--no_download', action='store_true', default=False,
        help = "Set to disable downloading models.")
    parser.add_argument('--data_dir', type=str, default = "DDI", 
        help = "Folder containing dataset to load. Structure should be: (1) `[data_dir]/images` contains all images; (2) `[data_dir]/ddi_metadata.csv` contains the CSV metadata for the DDI dataset")
    parser.add_argument('--eval_dir', type=str, default = "DDI-results", 
        help = "Folder to store evaluation results.")
    parser.add_argument('--use_gpu', action='store_true', default=False,
        help = "Set to use GPU for evaluation.")
    parser.add_argument('--plot', action='store_true', default=False,
        help = "Set to show ROC plot.")
    args = parser.parse_args()
    return args

def eval_model(model, dataset, use_gpu=False, show_plot=False):
    """Evaluate loaded model on provided image dataset. Assumes supplied image 
    directory corresponds to `root` input for torchvision.datasets.ImageFolder
    class. Assumes the data is split into binary/malignant labels, as this is 
    what our models are trained+evaluated on."""

    use_gpu = (use_gpu and torch.cuda.is_available())
    device = torch.device("cuda") if use_gpu else torch.device("cpu")

    # load dataset
    dataloader = torch.utils.data.DataLoader(
                    dataset,
                    batch_size=32, shuffle=False,
                    num_workers=0, pin_memory=use_gpu)

    # prepare model for evaluation
    model.to(device).eval()

    # log output for all images in dataset
    hat, star, all_paths = [], [], []
    for batch in tqdm.tqdm(enumerate(dataloader)):
        i, (paths, images, target, skin_tone) = batch
        images = images.to(device)
        target = target.to(device)

        with torch.no_grad():
            output = model(images)

        hat.append(output[:,1].detach().cpu().numpy())
        star.append(target.cpu().numpy())
        all_paths.append(paths)

    hat = np.concatenate(hat)
    star = np.concatenate(star)
    all_paths = np.concatenate(all_paths)
    threshold = model._ddi_threshold
    m_name = model._ddi_name
    m_web_path = model._ddi_web_path

    report = classification_report(star, (hat>threshold).astype(int), 
        target_names=["benign","malignant"])
    fpr, tpr, _ = roc_curve(star, hat, pos_label=1,
                                sample_weight=None,
                                drop_intermediate=True)
    auc_est = auc(fpr, tpr)

    if show_plot:
        _=plt.plot(fpr, tpr, 
            color = "blue", linestyle = "-", linewidth=2, 
            marker = "o", markersize=2, 
            label=f"AUC = {auc_est:.3f}")[0]
        plt.show()
        plt.close()

    eval_results = {'predicted_labels':hat, # predicted labels by model
                    'true_labels':star,     # true labels
                    'images':all_paths,     # image paths
                    'report':report,        # sklearn classification report
                    'ROC_AUC':auc_est,      # ROC-AUC
                    'threshold':threshold,  # >= threshold ==> malignant
                    'model':m_name,         # model name
                    'web_path':m_web_path,  # web link to download model
                    }

    return eval_results




if __name__ == '__main__':
    # get arguments from command line
    args = get_args()
    # load model and download if necessary
    model = load_model(args.model, 
        save_dir=args.model_dir, download=not args.no_download)
    # load DDI dataset
    dataset = DDI_Dataset("DDI", transform=test_transform)
    # evaluate results on data
    eval_results = eval_model(model, dataset, 
        use_gpu=args.use_gpu, show_plot=args.plot)

    # save evaluation results in a .pkl file 
    if args.eval_dir:
        os.makedirs(args.eval_dir, exist_ok=True)
        eval_save_path = os.path.join(args.eval_dir, 
                                      f"{args.model}-evaluation.pkl")
        with open(eval_save_path, 'wb') as f:
            pickle.dump(eval_results, f)

        # load results with:
        #with open(eval_save_path, 'rb') as f:
        #    results = pickle.load(f)

и вот полная трассировка:

Exception has occurred: Exception
Please visit <https://stanfordaimi.azurewebsites.net/datasets/35866158-8196-48d8-87bf-50dca81df965> to download the DDI dataset.
  File "C:\Users\User\OneDrive\desktop\CSproject\dataset\DDI\ddi_dataset.py", line 37, in __init__
    raise Exception(f"Please visit <{DDI_Dataset._DDI_download_link}> to download the DDI dataset.")
  File "C:\Users\User\OneDrive\desktop\CSproject\dataset\DDI\eval_ddi.py", line 140, in <module>
    dataset = DDI_Dataset("DDI", transform=test_transform)
              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Exception: Please visit <https://stanfordaimi.azurewebsites.net/datasets/35866158-8196-48d8-87bf-50dca81df965> to download the DDI dataset.

Я ожидаю узнать, почему возникает проблема и как ее решить.

Можете ли вы напечатать значение csv_path непосредственно перед исключением?

Pac0 21.07.2024 05:21

Здравствуйте, не могли бы вы добавить код, который вызывает (создает экземпляр) DDI_Dataset? Это очень поможет.

Luke L 21.07.2024 06:49

@pac0, вывод: DDI\ddi_metadata.csv

mousie 21.07.2024 07:03

@LukeL, извини, я не знаю, как точно вызвать (создать экземпляр) DDI_Dataset, но я попытался распечатать путь к файлу по коду (код: (1)print(os.path.abspath("ddi_dataset.py" )) ,(2)print(os.path.abspath("ddi_metadata.csv")) ; вывод: (1)C:\Users\User\OneDrive\desktop\CSproject\dataset\DDI\ddi_‌​dataset.py, (2)C:\Users\User\OneDrive\desktop\CSproject\dataset\DDI\ddi_‌​metadata.csv), помогут ли они, или я могу выполнить другие действия.

mousie 21.07.2024 07:21

Что ж, не исключено, что вы не создали экземпляр класса DDI_Dataset, потому что код в функции и классах не выполняются сами по себе, поэтому для возникновения ошибки вы должны были где-то его вызвать. По сути, я прошу вас указать место, где впервые была обнаружена ошибка.

Luke L 21.07.2024 07:25

@LukeL, я редактирую свои сообщения и вставляю код, вызывающий «DDI_Dataset», помогает ли информация там?

mousie 21.07.2024 08:05

Не могли бы вы еще отредактировать, чтобы включить полную обратную трассировку, используя форматирование кода?

tripleee 21.07.2024 08:14

@triplee, я добавляю это сейчас, поможет?

mousie 21.07.2024 08:43

Да, это очень помогает. Спасибо.

Luke L 21.07.2024 09:15
Почему в Python есть оператор "pass"?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Некоторые методы, о которых вы не знали, что они существуют в Python
Некоторые методы, о которых вы не знали, что они существуют в Python
Python - самый известный и самый простой в изучении язык в наши дни. Имея широкий спектр применения в области машинного обучения, Data Science,...
Основы Python Часть I
Основы Python Часть I
Вы когда-нибудь задумывались, почему в программах на Python вы видите приведенный ниже код?
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
Алиса и Боб имеют неориентированный граф из n узлов и трех типов ребер:
Оптимизация кода с помощью тернарного оператора Python
Оптимизация кода с помощью тернарного оператора Python
И последнее, что мы хотели бы показать вам, прежде чем двигаться дальше, это
Советы по эффективной веб-разработке с помощью Python
Советы по эффективной веб-разработке с помощью Python
Как веб-разработчик, Python может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
0
9
81
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Файл ddi_metadata.csv должен находиться в папке root, а не в images.

Извините, я переместил ddi_metadata.csv в корневую папку, но сообщение об ошибке все равно появляется.

mousie 21.07.2024 09:05

Введите r"C:\Users\User\OneDrive\desktop\CSproject\dataset\DDI" вместо просто "DDI" или убедитесь, что ваш рабочий каталог — C:\Users\User\OneDrive\desktop\CSproject\dataset; см. также Что такое текущий рабочий каталог?

tripleee 21.07.2024 09:16

Другие вопросы по теме