{
  "id": 419014,
  "title": "How to train Unet pytorch",
  "url": "/competitions/hubmap-hacking-the-human-vasculature/discussion/419014",
  "author_name": "",
  "post_date": "2023-06-23T17:44:55.158651200Z",
  "votes": 3,
  "comment_count": 4,
  "views": 0,
  "content": "<p>Guys this is my first topic ever, so please feel free to provide constructive feedback and guidance. I'm eager to learn the proper way of doing things around here, so don't hesitate to give me your honest opinions.</p>\n<p>Well, in short terms: Model always returns errors due to dicts, \"None\", ever torch zeros. We have some \"None\" in annotations to show model, that there is nothing to detect, but we need to fix it into <strong>getitem</strong> somehow. Any ideas? Maybe I do something totally wrong?</p>\n<p>Error examples: <br>\nTypeError: must be real number, not dict<br>\nTypeError: expected Tensor as element 1 in argument 0, but got list<br>\nTypeError: must be real number, not dict</p>\n<pre><code>tile_meta = pd.read_csv()\n (, )  json_file:\n    json_list = (json_file)\n\ntiles_dicts = []\n json_str  json_list:\n    tiles_dicts.append(json.loads(json_str))\n\nimage_ids = tile_meta[].unique().tolist()\nimage_paths = [.()    image_ids]\n\nannotations = []\n image_id  image_ids:\n    image_dict = ((item  item  tiles_dicts  item[] == image_id), )\n\n\n image_dict   :\n    image_annotations = image_dict[]\n    annotations.append(image_annotations)\n:\n      annotations.append()\n</code></pre>\n<p>Well, maybe we could change some params into SegmentationDataset…</p>\n<pre><code> torch\n torchvision.transforms  transforms\n PIL  Image\n\n (torch.utils.data.Dataset):\n     ():\n        self.image_paths = image_paths\n        self.annotations = annotations\n        self.transform = transforms.Compose([\n        transforms.ToTensor(),\n        transforms.Normalize(mean=[, , ], std=[, , ])\n    ])\n\n     ():\n         (self.image_paths)\n\n     ():\n        image_path = self.image_paths[index]\n        image = Image.(image_path).convert()\n        image = self.transform(image)\n\n        annotation = self.annotations[index]\n\n\n     annotation  :\n        annotation = torch.tensor(torch.zeros(image.shape[:], dtype=torch.float32))\n    \n    \n        \n\n     image, annotation`\n</code></pre>\n<p>Below is my model, maybe could be helpful.</p>\n<pre><code> torch\n torch.nn  nn\n torch.optim  optim\n torch.utils.data  DataLoader\n\n (nn.Module):\n     ():\n        (UNet, self).__init__()\n\n        \n        self.encoder1 = self.double_conv(in_channels, )\n        self.encoder2 = self.double_conv(, )\n        self.encoder3 = self.double_conv(, )\n        self.encoder4 = self.double_conv(, )\n\n        \n        self.decoder1 = self.double_conv( + , )\n        self.decoder2 = self.double_conv( + , )\n        self.decoder3 = self.double_conv( + , )\n\n        \n        self.final_conv = nn.Conv2d(, out_channels, kernel_size=)\n\n        \n        self.maxpool = nn.MaxPool2d(kernel_size=, stride=)\n        self.upsample = nn.Upsample(scale_factor=, mode=, align_corners=)\n\n     ():\n        \n        enc1 = self.encoder1(x)\n        enc2 = self.encoder2(self.maxpool(enc1))\n        enc3 = self.encoder3(self.maxpool(enc2))\n        enc4 = self.encoder4(self.maxpool(enc3))\n\n        \n        dec1 = self.decoder1(torch.cat([enc4, self.upsample(enc3)], dim=))\n        dec2 = self.decoder2(torch.cat([dec1, self.upsample(enc2)], dim=))\n        dec3 = self.decoder3(torch.cat([dec2, self.upsample(enc1)], dim=))\n\n        \n        output = self.final_conv(dec3)\n\n         output\n\n     ():\n         nn.Sequential(\n            nn.Conv2d(in_channels, out_channels, kernel_size=, padding=),\n            nn.ReLU(inplace=),\n            nn.Conv2d(out_channels, out_channels, kernel_size=, padding=),\n            nn.ReLU(inplace=)\n        )\n\n\nnum_epochs = \nbatch_size = \nin_channels = \nout_channels = \n\ntrain_dataset = SegmentationDataset(image_paths, annotations)\ntrain_loader = DataLoader(train_dataset, batch_size=batch_size, shuffle=)\n\n\nmodel = UNet(in_channels, out_channels)\n\n\ncriterion = nn.CrossEntropyLoss()\n\n\noptimizer = optim.Adam(model.parameters(), lr=)\n\n\ndevice = torch.device(  torch.cuda.is_available()  )\n\n\nmodel = model.to(device)\n\n\n epoch  (num_epochs):\n    model.train()  \n    running_loss = \n\n     images, labels  train_loader:\n        images = images.to(device)\n        labels = labels.to(device)\n\n        \n        outputs = model(images)\n\n        \n        loss = criterion(outputs, labels)\n\n        \n        optimizer.zero_grad()\n        loss.backward()\n        optimizer.step()\n\n        running_loss += loss.item() * images.size()\n\n    \n    epoch_loss = running_loss / (train_dataset)\n\n    \n    (\n</code></pre>",
  "messages": [
    {
      "id": "2314960",
      "postDate": "06/23/2023 17:44:55",
      "content": "<p>Guys this is my first topic ever, so please feel free to provide constructive feedback and guidance. I'm eager to learn the proper way of doing things around here, so don't hesitate to give me your honest opinions.</p>\n<p>Well, in short terms: Model always returns errors due to dicts, \"None\", ever torch zeros. We have some \"None\" in annotations to show model, that there is nothing to detect, but we need to fix it into <strong>getitem</strong> somehow. Any ideas? Maybe I do something totally wrong?</p>\n<p>Error examples: <br>\nTypeError: must be real number, not dict<br>\nTypeError: expected Tensor as element 1 in argument 0, but got list<br>\nTypeError: must be real number, not dict</p>\n<pre><code>tile_meta = pd.read_csv()\n (, )  json_file:\n    json_list = (json_file)\n\ntiles_dicts = []\n json_str  json_list:\n    tiles_dicts.append(json.loads(json_str))\n\nimage_ids = tile_meta[].unique().tolist()\nimage_paths = [.()    image_ids]\n\nannotations = []\n image_id  image_ids:\n    image_dict = ((item  item  tiles_dicts  item[] == image_id), )\n\n\n image_dict   :\n    image_annotations = image_dict[]\n    annotations.append(image_annotations)\n:\n      annotations.append()\n</code></pre>\n<p>Well, maybe we could change some params into SegmentationDataset…</p>\n<pre><code> torch\n torchvision.transforms  transforms\n PIL  Image\n\n (torch.utils.data.Dataset):\n     ():\n        self.image_paths = image_paths\n        self.annotations = annotations\n        self.transform = transforms.Compose([\n        transforms.ToTensor(),\n        transforms.Normalize(mean=[, , ], std=[, , ])\n    ])\n\n     ():\n         (self.image_paths)\n\n     ():\n        image_path = self.image_paths[index]\n        image = Image.(image_path).convert()\n        image = self.transform(image)\n\n        annotation = self.annotations[index]\n\n\n     annotation  :\n        annotation = torch.tensor(torch.zeros(image.shape[:], dtype=torch.float32))\n    \n    \n        \n\n     image, annotation`\n</code></pre>\n<p>Below is my model, maybe could be helpful.</p>\n<pre><code> torch\n torch.nn  nn\n torch.optim  optim\n torch.utils.data  DataLoader\n\n (nn.Module):\n     ():\n        (UNet, self).__init__()\n\n        \n        self.encoder1 = self.double_conv(in_channels, )\n        self.encoder2 = self.double_conv(, )\n        self.encoder3 = self.double_conv(, )\n        self.encoder4 = self.double_conv(, )\n\n        \n        self.decoder1 = self.double_conv( + , )\n        self.decoder2 = self.double_conv( + , )\n        self.decoder3 = self.double_conv( + , )\n\n        \n        self.final_conv = nn.Conv2d(, out_channels, kernel_size=)\n\n        \n        self.maxpool = nn.MaxPool2d(kernel_size=, stride=)\n        self.upsample = nn.Upsample(scale_factor=, mode=, align_corners=)\n\n     ():\n        \n        enc1 = self.encoder1(x)\n        enc2 = self.encoder2(self.maxpool(enc1))\n        enc3 = self.encoder3(self.maxpool(enc2))\n        enc4 = self.encoder4(self.maxpool(enc3))\n\n        \n        dec1 = self.decoder1(torch.cat([enc4, self.upsample(enc3)], dim=))\n        dec2 = self.decoder2(torch.cat([dec1, self.upsample(enc2)], dim=))\n        dec3 = self.decoder3(torch.cat([dec2, self.upsample(enc1)], dim=))\n\n        \n        output = self.final_conv(dec3)\n\n         output\n\n     ():\n         nn.Sequential(\n            nn.Conv2d(in_channels, out_channels, kernel_size=, padding=),\n            nn.ReLU(inplace=),\n            nn.Conv2d(out_channels, out_channels, kernel_size=, padding=),\n            nn.ReLU(inplace=)\n        )\n\n\nnum_epochs = \nbatch_size = \nin_channels = \nout_channels = \n\ntrain_dataset = SegmentationDataset(image_paths, annotations)\ntrain_loader = DataLoader(train_dataset, batch_size=batch_size, shuffle=)\n\n\nmodel = UNet(in_channels, out_channels)\n\n\ncriterion = nn.CrossEntropyLoss()\n\n\noptimizer = optim.Adam(model.parameters(), lr=)\n\n\ndevice = torch.device(  torch.cuda.is_available()  )\n\n\nmodel = model.to(device)\n\n\n epoch  (num_epochs):\n    model.train()  \n    running_loss = \n\n     images, labels  train_loader:\n        images = images.to(device)\n        labels = labels.to(device)\n\n        \n        outputs = model(images)\n\n        \n        loss = criterion(outputs, labels)\n\n        \n        optimizer.zero_grad()\n        loss.backward()\n        optimizer.step()\n\n        running_loss += loss.item() * images.size()\n\n    \n    epoch_loss = running_loss / (train_dataset)\n\n    \n    (\n</code></pre>",
      "rawMarkdown": "Guys this is my first topic ever, so please feel free to provide constructive feedback and guidance. I'm eager to learn the proper way of doing things around here, so don't hesitate to give me your honest opinions.\n\n\n\nWell, in short terms: Model always returns errors due to dicts, \"None\", ever torch zeros. We have some \"None\" in annotations to show model, that there is nothing to detect, but we need to fix it into __getitem__ somehow. Any ideas? Maybe I do something totally wrong?\n\nError examples: \nTypeError: must be real number, not dict\nTypeError: expected Tensor as element 1 in argument 0, but got list\nTypeError: must be real number, not dict\n\n    tile_meta = pd.read_csv('/kaggle/input/hubmap-hacking-the-human-vasculature/tile_meta.csv')\n    with open('/kaggle/input/hubmap-hacking-the-human-vasculature/polygons.jsonl', 'r') as json_file:\n        json_list = list(json_file)\n\n    tiles_dicts = []\n    for json_str in json_list:\n        tiles_dicts.append(json.loads(json_str))\n\n    image_ids = tile_meta['id'].unique().tolist()\n    image_paths = ['/kaggle/input/hubmap-hacking-the-human-vasculature/train/{}.tif'.format(id) for id in image_ids]\n\n    annotations = []\n    for image_id in image_ids:\n        image_dict = next((item for item in tiles_dicts if item['id'] == image_id), None)\n    \n    # HERE I SEE THE PROBLEM.\n    if image_dict is not None:\n        image_annotations = image_dict['annotations']\n        annotations.append(image_annotations)\n    else:\n          annotations.append(None)\n\n\nWell, maybe we could change some params into SegmentationDataset...\n\n    import torch\n    import torchvision.transforms as transforms\n    from PIL import Image\n\n    class SegmentationDataset(torch.utils.data.Dataset):\n        def __init__(self, image_paths, annotations):\n            self.image_paths = image_paths\n            self.annotations = annotations\n            self.transform = transforms.Compose([\n            transforms.ToTensor(),\n            transforms.Normalize(mean=[0.485, 0.456, 0.406], std=[0.229, 0.224, 0.225])\n        ])\n\n        def __len__(self):\n            return len(self.image_paths)\n\n        def __getitem__(self, index):\n            image_path = self.image_paths[index]\n            image = Image.open(image_path).convert('RGB')\n            image = self.transform(image)\n\n            annotation = self.annotations[index]\n\n    # HERE I SEE THE PROBLEM TOO\n        if annotation is None:\n            annotation = torch.tensor(torch.zeros(image.shape[1:], dtype=torch.float32))\n        # annotation = torch.zeros(image.shape[1:], dtype=torch.float32)\n        # else:\n            # annotation = torch.tensor(annotation, dtype=torch.float32)\n\n        return image, annotation`\n\nBelow is my model, maybe could be helpful.\n\n    import torch\n    import torch.nn as nn\n    import torch.optim as optim\n    from torch.utils.data import DataLoader\n\n    class UNet(nn.Module):\n        def __init__(self, in_channels, out_channels):\n            super(UNet, self).__init__()\n\n            # Encoder\n            self.encoder1 = self.double_conv(in_channels, 64)\n            self.encoder2 = self.double_conv(64, 128)\n            self.encoder3 = self.double_conv(128, 256)\n            self.encoder4 = self.double_conv(256, 512)\n\n            # Decoder\n            self.decoder1 = self.double_conv(512 + 256, 256)\n            self.decoder2 = self.double_conv(256 + 128, 128)\n            self.decoder3 = self.double_conv(128 + 64, 64)\n\n            # Final convolution\n            self.final_conv = nn.Conv2d(64, out_channels, kernel_size=1)\n\n            # Max pooling and upsampling\n            self.maxpool = nn.MaxPool2d(kernel_size=2, stride=2)\n            self.upsample = nn.Upsample(scale_factor=2, mode='bilinear', align_corners=True)\n\n        def forward(self, x):\n            # Encoder\n            enc1 = self.encoder1(x)\n            enc2 = self.encoder2(self.maxpool(enc1))\n            enc3 = self.encoder3(self.maxpool(enc2))\n            enc4 = self.encoder4(self.maxpool(enc3))\n\n            # Decoder\n            dec1 = self.decoder1(torch.cat([enc4, self.upsample(enc3)], dim=1))\n            dec2 = self.decoder2(torch.cat([dec1, self.upsample(enc2)], dim=1))\n            dec3 = self.decoder3(torch.cat([dec2, self.upsample(enc1)], dim=1))\n\n            # Final convolution\n            output = self.final_conv(dec3)\n\n            return output\n\n        def double_conv(self, in_channels, out_channels):\n            return nn.Sequential(\n                nn.Conv2d(in_channels, out_channels, kernel_size=3, padding=1),\n                nn.ReLU(inplace=True),\n                nn.Conv2d(out_channels, out_channels, kernel_size=3, padding=1),\n                nn.ReLU(inplace=True)\n            )\n\n    # Define the U-Net model\n    num_epochs = 3\n    batch_size = 64\n    in_channels = 3\n    out_channels = 1\n\n    train_dataset = SegmentationDataset(image_paths, annotations)\n    train_loader = DataLoader(train_dataset, batch_size=batch_size, shuffle=True)\n\n\n    model = UNet(in_channels, out_channels)\n\n    # Define the loss function\n    criterion = nn.CrossEntropyLoss()\n\n    # Define the optimizer\n    optimizer = optim.Adam(model.parameters(), lr=0.001)\n\n    # Set the device (GPU or CPU)\n    device = torch.device('cuda' if torch.cuda.is_available() else 'cpu')\n\n    # Transfer the model to the device\n    model = model.to(device)\n\n    # Training loop\n    for epoch in range(num_epochs):\n        model.train()  # Set the model to training mode\n        running_loss = 0.0\n\n        for images, labels in train_loader:\n            images = images.to(device)\n            labels = labels.to(device)\n\n            # Forward pass\n            outputs = model(images)\n\n            # Compute the loss\n            loss = criterion(outputs, labels)\n\n            # Backward and optimize\n            optimizer.zero_grad()\n            loss.backward()\n            optimizer.step()\n\n            running_loss += loss.item() * images.size(0)\n\n        # Compute the average loss for the epoch\n        epoch_loss = running_loss / len(train_dataset)\n\n        # Print the loss for each epoch\n        print(f'Epoch {epoch+1}/{num_epochs}, Loss: {epoch_loss:.4f}'",
      "votes": null
    },
    {
      "id": "2315565",
      "postDate": "06/24/2023 08:28:14",
      "content": "<p>You need to use <a href=\"https://github.com/qubvel/segmentation_models.pytorch\" target=\"_blank\">https://github.com/qubvel/segmentation_models.pytorch</a> and <a href=\"https://albumentations.ai/\" target=\"_blank\">https://albumentations.ai/</a></p>",
      "rawMarkdown": "You need to use https://github.com/qubvel/segmentation_models.pytorch and https://albumentations.ai/",
      "votes": null
    },
    {
      "id": "2315696",
      "postDate": "06/24/2023 10:26:39",
      "content": "<p>And what about kaggle kernel publishment? I mean, we cannot use internet and so on…</p>",
      "rawMarkdown": "And what about kaggle kernel publishment? I mean, we cannot use internet and so on...",
      "votes": null
    },
    {
      "id": "2366205",
      "postDate": "07/30/2023 19:53:30",
      "content": "<p>did you figure out the solution or did you opt out to install those dependencies through wheels?</p>",
      "rawMarkdown": "did you figure out the solution or did you opt out to install those dependencies through wheels?",
      "votes": null
    },
    {
      "id": "2367164",
      "postDate": "07/31/2023 12:00:02",
      "content": "<p>I dropped it, but wheels must be ok after bugfix</p>",
      "rawMarkdown": "I dropped it, but wheels must be ok after bugfix",
      "votes": null
    }
  ],
  "comments": [
    {
      "id": 2315565,
      "author_name": "dmitrykonovalov",
      "author_url": "",
      "post_date": "06/24/2023 08:28:14",
      "content": "<p>You need to use <a href=\"https://github.com/qubvel/segmentation_models.pytorch\" target=\"_blank\">https://github.com/qubvel/segmentation_models.pytorch</a> and <a href=\"https://albumentations.ai/\" target=\"_blank\">https://albumentations.ai/</a></p>",
      "votes": null,
      "replies": [
        {
          "id": 2315696,
          "author_name": "kapedalex",
          "author_url": "",
          "post_date": "06/24/2023 10:26:39",
          "content": "<p>And what about kaggle kernel publishment? I mean, we cannot use internet and so on…</p>",
          "votes": null,
          "replies": [
            {
              "id": 2366205,
              "author_name": "blueprint123",
              "author_url": "",
              "post_date": "07/30/2023 19:53:30",
              "content": "<p>did you figure out the solution or did you opt out to install those dependencies through wheels?</p>",
              "votes": null,
              "replies": [
                {
                  "id": 2367164,
                  "author_name": "kapedalex",
                  "author_url": "",
                  "post_date": "07/31/2023 12:00:02",
                  "content": "<p>I dropped it, but wheels must be ok after bugfix</p>",
                  "votes": null,
                  "replies": []
                }
              ]
            }
          ]
        }
      ]
    }
  ],
  "raw_markdown_by_id": {
    "2314960": "Guys this is my first topic ever, so please feel free to provide constructive feedback and guidance. I'm eager to learn the proper way of doing things around here, so don't hesitate to give me your honest opinions.\n\n\n\nWell, in short terms: Model always returns errors due to dicts, \"None\", ever torch zeros. We have some \"None\" in annotations to show model, that there is nothing to detect, but we need to fix it into __getitem__ somehow. Any ideas? Maybe I do something totally wrong?\n\nError examples: \nTypeError: must be real number, not dict\nTypeError: expected Tensor as element 1 in argument 0, but got list\nTypeError: must be real number, not dict\n\n    tile_meta = pd.read_csv('/kaggle/input/hubmap-hacking-the-human-vasculature/tile_meta.csv')\n    with open('/kaggle/input/hubmap-hacking-the-human-vasculature/polygons.jsonl', 'r') as json_file:\n        json_list = list(json_file)\n\n    tiles_dicts = []\n    for json_str in json_list:\n        tiles_dicts.append(json.loads(json_str))\n\n    image_ids = tile_meta['id'].unique().tolist()\n    image_paths = ['/kaggle/input/hubmap-hacking-the-human-vasculature/train/{}.tif'.format(id) for id in image_ids]\n\n    annotations = []\n    for image_id in image_ids:\n        image_dict = next((item for item in tiles_dicts if item['id'] == image_id), None)\n    \n    # HERE I SEE THE PROBLEM.\n    if image_dict is not None:\n        image_annotations = image_dict['annotations']\n        annotations.append(image_annotations)\n    else:\n          annotations.append(None)\n\n\nWell, maybe we could change some params into SegmentationDataset...\n\n    import torch\n    import torchvision.transforms as transforms\n    from PIL import Image\n\n    class SegmentationDataset(torch.utils.data.Dataset):\n        def __init__(self, image_paths, annotations):\n            self.image_paths = image_paths\n            self.annotations = annotations\n            self.transform = transforms.Compose([\n            transforms.ToTensor(),\n            transforms.Normalize(mean=[0.485, 0.456, 0.406], std=[0.229, 0.224, 0.225])\n        ])\n\n        def __len__(self):\n            return len(self.image_paths)\n\n        def __getitem__(self, index):\n            image_path = self.image_paths[index]\n            image = Image.open(image_path).convert('RGB')\n            image = self.transform(image)\n\n            annotation = self.annotations[index]\n\n    # HERE I SEE THE PROBLEM TOO\n        if annotation is None:\n            annotation = torch.tensor(torch.zeros(image.shape[1:], dtype=torch.float32))\n        # annotation = torch.zeros(image.shape[1:], dtype=torch.float32)\n        # else:\n            # annotation = torch.tensor(annotation, dtype=torch.float32)\n\n        return image, annotation`\n\nBelow is my model, maybe could be helpful.\n\n    import torch\n    import torch.nn as nn\n    import torch.optim as optim\n    from torch.utils.data import DataLoader\n\n    class UNet(nn.Module):\n        def __init__(self, in_channels, out_channels):\n            super(UNet, self).__init__()\n\n            # Encoder\n            self.encoder1 = self.double_conv(in_channels, 64)\n            self.encoder2 = self.double_conv(64, 128)\n            self.encoder3 = self.double_conv(128, 256)\n            self.encoder4 = self.double_conv(256, 512)\n\n            # Decoder\n            self.decoder1 = self.double_conv(512 + 256, 256)\n            self.decoder2 = self.double_conv(256 + 128, 128)\n            self.decoder3 = self.double_conv(128 + 64, 64)\n\n            # Final convolution\n            self.final_conv = nn.Conv2d(64, out_channels, kernel_size=1)\n\n            # Max pooling and upsampling\n            self.maxpool = nn.MaxPool2d(kernel_size=2, stride=2)\n            self.upsample = nn.Upsample(scale_factor=2, mode='bilinear', align_corners=True)\n\n        def forward(self, x):\n            # Encoder\n            enc1 = self.encoder1(x)\n            enc2 = self.encoder2(self.maxpool(enc1))\n            enc3 = self.encoder3(self.maxpool(enc2))\n            enc4 = self.encoder4(self.maxpool(enc3))\n\n            # Decoder\n            dec1 = self.decoder1(torch.cat([enc4, self.upsample(enc3)], dim=1))\n            dec2 = self.decoder2(torch.cat([dec1, self.upsample(enc2)], dim=1))\n            dec3 = self.decoder3(torch.cat([dec2, self.upsample(enc1)], dim=1))\n\n            # Final convolution\n            output = self.final_conv(dec3)\n\n            return output\n\n        def double_conv(self, in_channels, out_channels):\n            return nn.Sequential(\n                nn.Conv2d(in_channels, out_channels, kernel_size=3, padding=1),\n                nn.ReLU(inplace=True),\n                nn.Conv2d(out_channels, out_channels, kernel_size=3, padding=1),\n                nn.ReLU(inplace=True)\n            )\n\n    # Define the U-Net model\n    num_epochs = 3\n    batch_size = 64\n    in_channels = 3\n    out_channels = 1\n\n    train_dataset = SegmentationDataset(image_paths, annotations)\n    train_loader = DataLoader(train_dataset, batch_size=batch_size, shuffle=True)\n\n\n    model = UNet(in_channels, out_channels)\n\n    # Define the loss function\n    criterion = nn.CrossEntropyLoss()\n\n    # Define the optimizer\n    optimizer = optim.Adam(model.parameters(), lr=0.001)\n\n    # Set the device (GPU or CPU)\n    device = torch.device('cuda' if torch.cuda.is_available() else 'cpu')\n\n    # Transfer the model to the device\n    model = model.to(device)\n\n    # Training loop\n    for epoch in range(num_epochs):\n        model.train()  # Set the model to training mode\n        running_loss = 0.0\n\n        for images, labels in train_loader:\n            images = images.to(device)\n            labels = labels.to(device)\n\n            # Forward pass\n            outputs = model(images)\n\n            # Compute the loss\n            loss = criterion(outputs, labels)\n\n            # Backward and optimize\n            optimizer.zero_grad()\n            loss.backward()\n            optimizer.step()\n\n            running_loss += loss.item() * images.size(0)\n\n        # Compute the average loss for the epoch\n        epoch_loss = running_loss / len(train_dataset)\n\n        # Print the loss for each epoch\n        print(f'Epoch {epoch+1}/{num_epochs}, Loss: {epoch_loss:.4f}'",
    "2315565": "You need to use https://github.com/qubvel/segmentation_models.pytorch and https://albumentations.ai/",
    "2315696": "And what about kaggle kernel publishment? I mean, we cannot use internet and so on...",
    "2366205": "did you figure out the solution or did you opt out to install those dependencies through wheels?",
    "2367164": "I dropped it, but wheels must be ok after bugfix"
  },
  "source": "meta"
}