{
  "id": 48169,
  "title": "Share my progress, looking for advices (LB 0.78)",
  "url": "/competitions/sp-society-camera-model-identification/discussion/48169",
  "author_name": "",
  "post_date": "2018-01-24T05:35:13.844090300Z",
  "votes": 10,
  "comment_count": 8,
  "views": 0,
  "content": "<p>Hi guys,</p>\n\n<p>I am new to the competition, this is my first Kaggle task on image classification. I managed to learn a lot from the discussions in the past two weeks and did a lot of experiments. My LB score went up from 0.34 to 0.78 due to continuous improvement. I'd like to share my findings and also looking for advises.</p>\n\n<p><strong>Past Approach:</strong></p>\n\n<p>I started from transfer learning with ResNet50 using Keras. Only fine-tuning FC layers. My typical FC layers would be 512-256-10, 256-512-128-10 or 1024-1024-10 with dropout 0.5. What I observed were similar performance after 35 epochs (batch 48-120 with 10000 // batch_size steps). The loss and val_loss was very difficult to minimize somehow. I tried different optimizers, like SGD and Adam, and used lr_reduer and different configurations on lr_scheduler. Only by chance, I only had once with minimized the loss below 0.1. With these approaches, I had the following tensorboard chart. I was basically stuck in this approach.</p>\n\n<p><img src=\"https://cdn.pbrd.co/images/H4mc4Nwf.png\" alt=\"enter image description here\"></p>\n\n<p>The data generation was done by prepossessing the images and cropping random patches (224x224) then saving them into new folders. I generated more than 1 millions images. I tried to save patches using TIFF format to preserve the content, but it gave me a dataset more than 120GB!</p>\n\n<p><strong>Current Approach:</strong></p>\n\n<p>I realized there were probably few mistakes I made in the past. For example:</p>\n\n<ul>\n<li>I saved the patches into jpeg files with quality=100, but jpeg is not lossless format, it may have an impact.</li>\n<li>Even with 1 millions samples, after 100 epochs I will run out of samples with 10000 samples per epoch.</li>\n<li>Only fine-tuning FC layers seemed a dead-end to me. I don't have a powerful GPU to speed up my experiments.</li>\n</ul>\n\n<p>After reading all the topics on this forum, I found people mentioning the solution in the past competition called Cdiscount's Image Classification. The detailed description is <a href=\"https://www.kaggle.com/c/cdiscount-image-classification-challenge/discussion/45863\">here</a>.</p>\n\n<p>Here's the take out:</p>\n\n<ul>\n<li>I wrote a Keras generator randomly select one image from each category, doing random cropping for each loaded image will give me a good set of samples for each batch. No jpeg file on the disk, the numpy array will preserve the original content.</li>\n<li>Load pretrained weights of ResNet50, replace the FC layers and retrain the whole network. With more than a million (more like unlimited) images, we should be able to generalize better.</li>\n<li>Lengthen the steps in each epoch and use smaller batch size (this is because of my GPU memory limit), I went from 10k samples with batch size 120 to 50k samples with batch size 32 for each epoch.</li>\n<li>Use Adam with LearningRateScheduler settings from <a href=\"https://www.kaggle.com/c/cdiscount-image-classification-challenge/discussion/45863\">here</a>.</li>\n<li>Validation set is simply center crop on all 2750 images.</li>\n</ul>\n\n<p><img src=\"https://cdn.pbrd.co/images/H4ml1YE.png\" alt=\"enter image description here\"></p>\n\n<p>I ended up having this awesome tensorboard chart. It was not perfect, and took me 17 hours to train. But without <strong>additional data</strong> and no image manipulations, I managed to achieve 0.78 on LB. The FC layers were very simple indeed, only 32-10.</p>\n\n<p>But there was still a huge gap. I achieved 98% acc and 90% val_acc, but LB only gives me 78%. I tried another similar network after this, but didn't give me better result.</p>\n\n<p>Mistakes I made that wasted me a lot of time:</p>\n\n<ul>\n<li>np.asarray(img) uses uint8 by default, I have wasted days on this simply code that always gives me bad results regardless of how well I train. Change it to np.asarray(img, dtype=np.float32) giving me a big improvement.</li>\n<li>Resizing the test image into 224x224 was a bad idea. I ended up using the center patch of the test image.</li>\n<li>Averaging may yield slightly better result. I cropped 5 patches from test image (center, four corners) and averaged the prediction.</li>\n</ul>\n\n<p>Any comments in how to improve the gap between training and LB?</p>\n\n<p>Shunjia</p>",
  "messages": [
    {
      "id": "273087",
      "postDate": "01/24/2018 05:35:13",
      "content": "<p>Hi guys,</p>\n\n<p>I am new to the competition, this is my first Kaggle task on image classification. I managed to learn a lot from the discussions in the past two weeks and did a lot of experiments. My LB score went up from 0.34 to 0.78 due to continuous improvement. I'd like to share my findings and also looking for advises.</p>\n\n<p><strong>Past Approach:</strong></p>\n\n<p>I started from transfer learning with ResNet50 using Keras. Only fine-tuning FC layers. My typical FC layers would be 512-256-10, 256-512-128-10 or 1024-1024-10 with dropout 0.5. What I observed were similar performance after 35 epochs (batch 48-120 with 10000 // batch_size steps). The loss and val_loss was very difficult to minimize somehow. I tried different optimizers, like SGD and Adam, and used lr_reduer and different configurations on lr_scheduler. Only by chance, I only had once with minimized the loss below 0.1. With these approaches, I had the following tensorboard chart. I was basically stuck in this approach.</p>\n\n<p><img src=\"https://cdn.pbrd.co/images/H4mc4Nwf.png\" alt=\"enter image description here\"></p>\n\n<p>The data generation was done by prepossessing the images and cropping random patches (224x224) then saving them into new folders. I generated more than 1 millions images. I tried to save patches using TIFF format to preserve the content, but it gave me a dataset more than 120GB!</p>\n\n<p><strong>Current Approach:</strong></p>\n\n<p>I realized there were probably few mistakes I made in the past. For example:</p>\n\n<ul>\n<li>I saved the patches into jpeg files with quality=100, but jpeg is not lossless format, it may have an impact.</li>\n<li>Even with 1 millions samples, after 100 epochs I will run out of samples with 10000 samples per epoch.</li>\n<li>Only fine-tuning FC layers seemed a dead-end to me. I don't have a powerful GPU to speed up my experiments.</li>\n</ul>\n\n<p>After reading all the topics on this forum, I found people mentioning the solution in the past competition called Cdiscount's Image Classification. The detailed description is <a href=\"https://www.kaggle.com/c/cdiscount-image-classification-challenge/discussion/45863\">here</a>.</p>\n\n<p>Here's the take out:</p>\n\n<ul>\n<li>I wrote a Keras generator randomly select one image from each category, doing random cropping for each loaded image will give me a good set of samples for each batch. No jpeg file on the disk, the numpy array will preserve the original content.</li>\n<li>Load pretrained weights of ResNet50, replace the FC layers and retrain the whole network. With more than a million (more like unlimited) images, we should be able to generalize better.</li>\n<li>Lengthen the steps in each epoch and use smaller batch size (this is because of my GPU memory limit), I went from 10k samples with batch size 120 to 50k samples with batch size 32 for each epoch.</li>\n<li>Use Adam with LearningRateScheduler settings from <a href=\"https://www.kaggle.com/c/cdiscount-image-classification-challenge/discussion/45863\">here</a>.</li>\n<li>Validation set is simply center crop on all 2750 images.</li>\n</ul>\n\n<p><img src=\"https://cdn.pbrd.co/images/H4ml1YE.png\" alt=\"enter image description here\"></p>\n\n<p>I ended up having this awesome tensorboard chart. It was not perfect, and took me 17 hours to train. But without <strong>additional data</strong> and no image manipulations, I managed to achieve 0.78 on LB. The FC layers were very simple indeed, only 32-10.</p>\n\n<p>But there was still a huge gap. I achieved 98% acc and 90% val_acc, but LB only gives me 78%. I tried another similar network after this, but didn't give me better result.</p>\n\n<p>Mistakes I made that wasted me a lot of time:</p>\n\n<ul>\n<li>np.asarray(img) uses uint8 by default, I have wasted days on this simply code that always gives me bad results regardless of how well I train. Change it to np.asarray(img, dtype=np.float32) giving me a big improvement.</li>\n<li>Resizing the test image into 224x224 was a bad idea. I ended up using the center patch of the test image.</li>\n<li>Averaging may yield slightly better result. I cropped 5 patches from test image (center, four corners) and averaged the prediction.</li>\n</ul>\n\n<p>Any comments in how to improve the gap between training and LB?</p>\n\n<p>Shunjia</p>",
      "rawMarkdown": "Hi guys,\n\nI am new to the competition, this is my first Kaggle task on image classification. I managed to learn a lot from the discussions in the past two weeks and did a lot of experiments. My LB score went up from 0.34 to 0.78 due to continuous improvement. I'd like to share my findings and also looking for advises.\n\n**Past Approach:**\n\nI started from transfer learning with ResNet50 using Keras. Only fine-tuning FC layers. My typical FC layers would be 512-256-10, 256-512-128-10 or 1024-1024-10 with dropout 0.5. What I observed were similar performance after 35 epochs (batch 48-120 with 10000 // batch_size steps). The loss and val_loss was very difficult to minimize somehow. I tried different optimizers, like SGD and Adam, and used lr_reduer and different configurations on lr_scheduler. Only by chance, I only had once with minimized the loss below 0.1. With these approaches, I had the following tensorboard chart. I was basically stuck in this approach.\n\n![enter image description here][1]\n\nThe data generation was done by prepossessing the images and cropping random patches (224x224) then saving them into new folders. I generated more than 1 millions images. I tried to save patches using TIFF format to preserve the content, but it gave me a dataset more than 120GB!\n\n**Current Approach:**\n\nI realized there were probably few mistakes I made in the past. For example:\n\n - I saved the patches into jpeg files with quality=100, but jpeg is not lossless format, it may have an impact.\n - Even with 1 millions samples, after 100 epochs I will run out of samples with 10000 samples per epoch.\n - Only fine-tuning FC layers seemed a dead-end to me. I don't have a powerful GPU to speed up my experiments.\n\nAfter reading all the topics on this forum, I found people mentioning the solution in the past competition called Cdiscount's Image Classification. The detailed description is [here][2].\n\nHere's the take out:\n\n- I wrote a Keras generator randomly select one image from each category, doing random cropping for each loaded image will give me a good set of samples for each batch. No jpeg file on the disk, the numpy array will preserve the original content.\n- Load pretrained weights of ResNet50, replace the FC layers and retrain the whole network. With more than a million (more like unlimited) images, we should be able to generalize better.\n- Lengthen the steps in each epoch and use smaller batch size (this is because of my GPU memory limit), I went from 10k samples with batch size 120 to 50k samples with batch size 32 for each epoch.\n- Use Adam with LearningRateScheduler settings from [here][3].\n- Validation set is simply center crop on all 2750 images.\n\n![enter image description here][4]\n\nI ended up having this awesome tensorboard chart. It was not perfect, and took me 17 hours to train. But without **additional data** and no image manipulations, I managed to achieve 0.78 on LB. The FC layers were very simple indeed, only 32-10.\n\nBut there was still a huge gap. I achieved 98% acc and 90% val_acc, but LB only gives me 78%. I tried another similar network after this, but didn't give me better result.\n\nMistakes I made that wasted me a lot of time:\n\n- np.asarray(img) uses uint8 by default, I have wasted days on this simply code that always gives me bad results regardless of how well I train. Change it to np.asarray(img, dtype=np.float32) giving me a big improvement.\n- Resizing the test image into 224x224 was a bad idea. I ended up using the center patch of the test image.\n- Averaging may yield slightly better result. I cropped 5 patches from test image (center, four corners) and averaged the prediction.\n\nAny comments in how to improve the gap between training and LB?\n\nShunjia\n\n  [1]: https://cdn.pbrd.co/images/H4mc4Nwf.png\n  [2]: https://www.kaggle.com/c/cdiscount-image-classification-challenge/discussion/45863\n  [3]: https://www.kaggle.com/c/cdiscount-image-classification-challenge/discussion/45863\n  [4]: https://cdn.pbrd.co/images/H4ml1YE.png",
      "votes": null
    },
    {
      "id": "273272",
      "postDate": "01/24/2018 11:46:20",
      "content": "<p>Hi, Shunjia. Thanks for your sharing. Why cropping images into 224x224 patches instead of 512x512 (size of the test set images)?</p>",
      "rawMarkdown": "Hi, Shunjia. Thanks for your sharing. Why cropping images into 224x224 patches instead of 512x512 (size of the test set images)?",
      "votes": null
    },
    {
      "id": "273317",
      "postDate": "01/24/2018 12:55:40",
      "content": "<p>Thank you!</p>",
      "rawMarkdown": "Thank you!",
      "votes": null
    },
    {
      "id": "273373",
      "postDate": "01/24/2018 14:28:21",
      "content": "<p>I think LB 0.78 is great considering you're just using original dataset and if I understand correclty you're mixing validation and train samples (very likely the center crop you used for validation has been seen by the network during training). </p>\n\n<p>Do you do any preprocessing before feeding it to the ResNet50?</p>",
      "rawMarkdown": "I think LB 0.78 is great considering you're just using original dataset and if I understand correclty you're mixing validation and train samples (very likely the center crop you used for validation has been seen by the network during training). \n\nDo you do any preprocessing before feeding it to the ResNet50?",
      "votes": null
    },
    {
      "id": "273524",
      "postDate": "01/24/2018 18:10:01",
      "content": "<p>Good point, I thought I can only feed ResNet50 with 224x224, I will try 512x512 to see if there will be any improvements.</p>",
      "rawMarkdown": "Good point, I thought I can only feed ResNet50 with 224x224, I will try 512x512 to see if there will be any improvements.",
      "votes": null
    },
    {
      "id": "273527",
      "postDate": "01/24/2018 18:13:02",
      "content": "<p>Yes, I think it's likely that the center crop or similar area has been seen in the training set. I will try to use Gleb as validation set to figure out the discrepancies.</p>\n\n<p>I don't do any preprocessing of ResNet50, I simply use the ResNet50 implementation from Keras.</p>",
      "rawMarkdown": "Yes, I think it's likely that the center crop or similar area has been seen in the training set. I will try to use Gleb as validation set to figure out the discrepancies.\n\nI don't do any preprocessing of ResNet50, I simply use the ResNet50 implementation from Keras.",
      "votes": null
    },
    {
      "id": "273543",
      "postDate": "01/24/2018 18:43:06",
      "content": "<p>Thanks for sharing your approach, I have followed your approach and trained full ResNet50 model, instead of just FC layers. I got the LB 80.9% (without image manipulations, and did not used Gleb's data). A small thought on the gap between LB and validation - Since I have not yet trained my model on test set image manipulations, I have submitted blanks for 'manip' images, and got accuracy score for only 'unalt' images as 0.621. And since the weight for unaltered images is 0.7, the real accuracy is 88.7%, and my validation accuracy is 96%, which is not too far I guess. And any thoughts on why training the whole ResNet model gave very big improvement as compared to training only FC layers?</p>",
      "rawMarkdown": "Thanks for sharing your approach, I have followed your approach and trained full ResNet50 model, instead of just FC layers. I got the LB 80.9% (without image manipulations, and did not used Gleb's data). A small thought on the gap between LB and validation - Since I have not yet trained my model on test set image manipulations, I have submitted blanks for 'manip' images, and got accuracy score for only 'unalt' images as 0.621. And since the weight for unaltered images is 0.7, the real accuracy is 88.7%, and my validation accuracy is 96%, which is not too far I guess. And any thoughts on why training the whole ResNet model gave very big improvement as compared to training only FC layers?",
      "votes": null
    },
    {
      "id": "273608",
      "postDate": "01/24/2018 21:44:48",
      "content": "<p>Awesome! In my opinion, only training the FC layers won't be enough because ResNet50 trained against ImageNet dataset. It was able to capture high level features to recognizing objects. But I am not sure if this is the case in identifying camera models.</p>",
      "rawMarkdown": "Awesome! In my opinion, only training the FC layers won't be enough because ResNet50 trained against ImageNet dataset. It was able to capture high level features to recognizing objects. But I am not sure if this is the case in identifying camera models.",
      "votes": null
    },
    {
      "id": "277243",
      "postDate": "02/02/2018 16:26:48",
      "content": "<p>Thanks buddy.  I've met a similar situation. Now I'm struggling. Your experience may be helpful for me.</p>",
      "rawMarkdown": "Thanks buddy.  I've met a similar situation. Now I'm struggling. Your experience may be helpful for me.",
      "votes": null
    }
  ],
  "comments": [
    {
      "id": 273272,
      "author_name": "shuhuagao",
      "author_url": "",
      "post_date": "01/24/2018 11:46:20",
      "content": "<p>Hi, Shunjia. Thanks for your sharing. Why cropping images into 224x224 patches instead of 512x512 (size of the test set images)?</p>",
      "votes": null,
      "replies": [
        {
          "id": 273524,
          "author_name": "shunjiading",
          "author_url": "",
          "post_date": "01/24/2018 18:10:01",
          "content": "<p>Good point, I thought I can only feed ResNet50 with 224x224, I will try 512x512 to see if there will be any improvements.</p>",
          "votes": null,
          "replies": []
        }
      ]
    },
    {
      "id": 273317,
      "author_name": "yyqing",
      "author_url": "",
      "post_date": "01/24/2018 12:55:40",
      "content": "<p>Thank you!</p>",
      "votes": null,
      "replies": []
    },
    {
      "id": 273373,
      "author_name": "antorsae",
      "author_url": "",
      "post_date": "01/24/2018 14:28:21",
      "content": "<p>I think LB 0.78 is great considering you're just using original dataset and if I understand correclty you're mixing validation and train samples (very likely the center crop you used for validation has been seen by the network during training). </p>\n\n<p>Do you do any preprocessing before feeding it to the ResNet50?</p>",
      "votes": null,
      "replies": [
        {
          "id": 273527,
          "author_name": "shunjiading",
          "author_url": "",
          "post_date": "01/24/2018 18:13:02",
          "content": "<p>Yes, I think it's likely that the center crop or similar area has been seen in the training set. I will try to use Gleb as validation set to figure out the discrepancies.</p>\n\n<p>I don't do any preprocessing of ResNet50, I simply use the ResNet50 implementation from Keras.</p>",
          "votes": null,
          "replies": []
        }
      ]
    },
    {
      "id": 273543,
      "author_name": "janardhanadapa",
      "author_url": "",
      "post_date": "01/24/2018 18:43:06",
      "content": "<p>Thanks for sharing your approach, I have followed your approach and trained full ResNet50 model, instead of just FC layers. I got the LB 80.9% (without image manipulations, and did not used Gleb's data). A small thought on the gap between LB and validation - Since I have not yet trained my model on test set image manipulations, I have submitted blanks for 'manip' images, and got accuracy score for only 'unalt' images as 0.621. And since the weight for unaltered images is 0.7, the real accuracy is 88.7%, and my validation accuracy is 96%, which is not too far I guess. And any thoughts on why training the whole ResNet model gave very big improvement as compared to training only FC layers?</p>",
      "votes": null,
      "replies": [
        {
          "id": 273608,
          "author_name": "shunjiading",
          "author_url": "",
          "post_date": "01/24/2018 21:44:48",
          "content": "<p>Awesome! In my opinion, only training the FC layers won't be enough because ResNet50 trained against ImageNet dataset. It was able to capture high level features to recognizing objects. But I am not sure if this is the case in identifying camera models.</p>",
          "votes": null,
          "replies": []
        }
      ]
    },
    {
      "id": 277243,
      "author_name": "vivalavida1989",
      "author_url": "",
      "post_date": "02/02/2018 16:26:48",
      "content": "<p>Thanks buddy.  I've met a similar situation. Now I'm struggling. Your experience may be helpful for me.</p>",
      "votes": null,
      "replies": []
    }
  ],
  "raw_markdown_by_id": {
    "273087": "Hi guys,\n\nI am new to the competition, this is my first Kaggle task on image classification. I managed to learn a lot from the discussions in the past two weeks and did a lot of experiments. My LB score went up from 0.34 to 0.78 due to continuous improvement. I'd like to share my findings and also looking for advises.\n\n**Past Approach:**\n\nI started from transfer learning with ResNet50 using Keras. Only fine-tuning FC layers. My typical FC layers would be 512-256-10, 256-512-128-10 or 1024-1024-10 with dropout 0.5. What I observed were similar performance after 35 epochs (batch 48-120 with 10000 // batch_size steps). The loss and val_loss was very difficult to minimize somehow. I tried different optimizers, like SGD and Adam, and used lr_reduer and different configurations on lr_scheduler. Only by chance, I only had once with minimized the loss below 0.1. With these approaches, I had the following tensorboard chart. I was basically stuck in this approach.\n\n![enter image description here][1]\n\nThe data generation was done by prepossessing the images and cropping random patches (224x224) then saving them into new folders. I generated more than 1 millions images. I tried to save patches using TIFF format to preserve the content, but it gave me a dataset more than 120GB!\n\n**Current Approach:**\n\nI realized there were probably few mistakes I made in the past. For example:\n\n - I saved the patches into jpeg files with quality=100, but jpeg is not lossless format, it may have an impact.\n - Even with 1 millions samples, after 100 epochs I will run out of samples with 10000 samples per epoch.\n - Only fine-tuning FC layers seemed a dead-end to me. I don't have a powerful GPU to speed up my experiments.\n\nAfter reading all the topics on this forum, I found people mentioning the solution in the past competition called Cdiscount's Image Classification. The detailed description is [here][2].\n\nHere's the take out:\n\n- I wrote a Keras generator randomly select one image from each category, doing random cropping for each loaded image will give me a good set of samples for each batch. No jpeg file on the disk, the numpy array will preserve the original content.\n- Load pretrained weights of ResNet50, replace the FC layers and retrain the whole network. With more than a million (more like unlimited) images, we should be able to generalize better.\n- Lengthen the steps in each epoch and use smaller batch size (this is because of my GPU memory limit), I went from 10k samples with batch size 120 to 50k samples with batch size 32 for each epoch.\n- Use Adam with LearningRateScheduler settings from [here][3].\n- Validation set is simply center crop on all 2750 images.\n\n![enter image description here][4]\n\nI ended up having this awesome tensorboard chart. It was not perfect, and took me 17 hours to train. But without **additional data** and no image manipulations, I managed to achieve 0.78 on LB. The FC layers were very simple indeed, only 32-10.\n\nBut there was still a huge gap. I achieved 98% acc and 90% val_acc, but LB only gives me 78%. I tried another similar network after this, but didn't give me better result.\n\nMistakes I made that wasted me a lot of time:\n\n- np.asarray(img) uses uint8 by default, I have wasted days on this simply code that always gives me bad results regardless of how well I train. Change it to np.asarray(img, dtype=np.float32) giving me a big improvement.\n- Resizing the test image into 224x224 was a bad idea. I ended up using the center patch of the test image.\n- Averaging may yield slightly better result. I cropped 5 patches from test image (center, four corners) and averaged the prediction.\n\nAny comments in how to improve the gap between training and LB?\n\nShunjia\n\n  [1]: https://cdn.pbrd.co/images/H4mc4Nwf.png\n  [2]: https://www.kaggle.com/c/cdiscount-image-classification-challenge/discussion/45863\n  [3]: https://www.kaggle.com/c/cdiscount-image-classification-challenge/discussion/45863\n  [4]: https://cdn.pbrd.co/images/H4ml1YE.png",
    "273272": "Hi, Shunjia. Thanks for your sharing. Why cropping images into 224x224 patches instead of 512x512 (size of the test set images)?",
    "273317": "Thank you!",
    "273373": "I think LB 0.78 is great considering you're just using original dataset and if I understand correclty you're mixing validation and train samples (very likely the center crop you used for validation has been seen by the network during training). \n\nDo you do any preprocessing before feeding it to the ResNet50?",
    "273524": "Good point, I thought I can only feed ResNet50 with 224x224, I will try 512x512 to see if there will be any improvements.",
    "273527": "Yes, I think it's likely that the center crop or similar area has been seen in the training set. I will try to use Gleb as validation set to figure out the discrepancies.\n\nI don't do any preprocessing of ResNet50, I simply use the ResNet50 implementation from Keras.",
    "273543": "Thanks for sharing your approach, I have followed your approach and trained full ResNet50 model, instead of just FC layers. I got the LB 80.9% (without image manipulations, and did not used Gleb's data). A small thought on the gap between LB and validation - Since I have not yet trained my model on test set image manipulations, I have submitted blanks for 'manip' images, and got accuracy score for only 'unalt' images as 0.621. And since the weight for unaltered images is 0.7, the real accuracy is 88.7%, and my validation accuracy is 96%, which is not too far I guess. And any thoughts on why training the whole ResNet model gave very big improvement as compared to training only FC layers?",
    "273608": "Awesome! In my opinion, only training the FC layers won't be enough because ResNet50 trained against ImageNet dataset. It was able to capture high level features to recognizing objects. But I am not sure if this is the case in identifying camera models.",
    "277243": "Thanks buddy.  I've met a similar situation. Now I'm struggling. Your experience may be helpful for me."
  },
  "source": "meta"
}