{
  "id": 11534,
  "title": "Interested in sharing strategies for CNNs?",
  "url": "/competitions/datasciencebowl/discussion/11534",
  "author_name": "",
  "post_date": "2015-01-16T20:18:33.990Z",
  "votes": 1,
  "comment_count": 34,
  "views": 14038,
  "content": "<p>Hi everyone,</p>\n<p>I was wondering if anyone is interesting in sharing training strategies for convolutional neural nets (or other deep learners)? We don't have to team up or share code, I thought it may just be useful to bounce successful/unsuccessful ideas of each other.&nbsp;</p>\n<p>If anyone is interested (and I will share first) please&nbsp;let me know and we can email.&nbsp;</p>",
  "messages": [
    {
      "id": "62799",
      "postDate": "01/16/2015 20:18:33",
      "content": "<p>Hi everyone,</p>\n<p>I was wondering if anyone is interesting in sharing training strategies for convolutional neural nets (or other deep learners)? We don't have to team up or share code, I thought it may just be useful to bounce successful/unsuccessful ideas of each other.&nbsp;</p>\n<p>If anyone is interested (and I will share first) please&nbsp;let me know and we can email.&nbsp;</p>",
      "rawMarkdown": "",
      "votes": null
    },
    {
      "id": "62801",
      "postDate": "01/16/2015 20:25:41",
      "content": "<p>You can share within a team or share on the forum, but it is against the rules to bounce ideas off of each other in email unless you are on the same team.</p>",
      "rawMarkdown": "",
      "votes": null
    },
    {
      "id": "62802",
      "postDate": "01/16/2015 20:31:48",
      "content": "<p>Sorry, I did not know that. &nbsp;I guess I then withdraw this forum post.&nbsp;</p>",
      "rawMarkdown": "",
      "votes": null
    },
    {
      "id": "62807",
      "postDate": "01/17/2015 00:09:56",
      "content": "<p>James,&nbsp;<br><br>Where does it specifically say we are unable to share ideas privately? I only see rules for code.&nbsp;<br><br>How are people supposed to team up without sharing any ideas prior? Seems like a poor strategy to blindly team up with another competitor with no insight into their methodology.&nbsp;</p>",
      "rawMarkdown": "",
      "votes": null
    },
    {
      "id": "62809",
      "postDate": "01/17/2015 01:03:49",
      "content": "<p>It's true the rules only refer to sharing code and data, which strikes me as strange since in most competitions you could easily describe your whole approach in an easy to replicate way without sharing any code or data. If someone describes their entire convnet architecture and data augmentation scheme, that's just as good as sharing the code.</p>\n\n<p>As far as blindly teaming up with no insight into each other's methodology, that's how I've always done it.</p>",
      "rawMarkdown": "",
      "votes": null
    },
    {
      "id": "62810",
      "postDate": "01/17/2015 02:51:52",
      "content": "<p>To stay within the rules I don't mind having the conversation here. Basically I am interested in which architecture&nbsp;people are using to train their CNNs. I am currently using a pure theano approach (similar to this <a href=\"http://www.deeplearning.net/tutorial/lenet.html#lenet\">theano CNN</a>) but cannot seem to break the 1.2 barrier in my error score.&nbsp;</p>\n<p>Are people using (or have used in the past) any &quot;black box&quot; architectures such as Caffe or cuda-ConvNet2, or any others?</p>\n<p>Considering I am still&nbsp;getting a score about twice that of the leading scores right now I am keen tp try some new approaches.&nbsp;</p>",
      "rawMarkdown": "",
      "votes": null
    },
    {
      "id": "62811",
      "postDate": "01/17/2015 03:53:38",
      "content": "<p>I started with the cxxnet kaggle bowl example and built on that. It's not a very complex architecture, so I had to beef it up a bit. Data augmentation helps quite a bit.</p>",
      "rawMarkdown": "",
      "votes": null
    },
    {
      "id": "62823",
      "postDate": "01/17/2015 09:54:48",
      "content": "<p>James, that's quite impressive that you blindly team up with people without sharing strategies prior. I doubt many other competitors do the same (especially in late game). It'd be interesting to see how effective that strategy is in practice.&nbsp;</p>\n<p>How would a rule on sharing ideas privately even be enforced?&nbsp;<br><br>From my experience with past kaggle competitions, there's always been sharing of ideas between competitors in private. Heck, I speak to competitors in private about ideas without the intention to compete myself.&nbsp;<br><br>In my opinion, there's a big difference between sharing strategies that may help a fellow competitor improve their skills as a data scientist, and giving away a winning strategy. (Hell, if you have a winning strategy, why would you share it in the first place?). If someone takes the time to show that they have a willingness to learn by asking questions to fellow competitors in private, then I have no qualms with helping as much as I can. I feel it's ridiculous to impose the constraint that those ideas must be made public.<br><br>Anyway, Mike, while I have not made a submission yet, I've had decent&nbsp;results with building an augmented dataset of the training data (CV results are ~0.9-1.09 log-loss) with a simple 2 layer CNN (100, 150 filters with max pooling) with a 500-121 hidden unit dense layer with a softmax classifier.<br><br>Augmentation of the dataset includes: random rotation (between 0-360), random cropping, and random mirroring.&nbsp;</p>",
      "rawMarkdown": "",
      "votes": null
    },
    {
      "id": "62829",
      "postDate": "01/17/2015 14:16:56",
      "content": "<p>Miroslaw,</p>\n<p>Thanks for the info. I think one of my big problems is I do no data augmentation, I just take the raw pixels as is and feed that to my net. Can you explain a bit on how to do this properly or point me to some references that go through it in detail.&nbsp;</p>\n<p>Also, I have seen winning solutions in other image classification competitions (<a href=\"https://github.com/benanne/kaggle-galaxies\">kaggle-galaxies</a>) blend multiple models together. Do you have a good idea of what they are doing here?</p>\n<p>Thanks!</p>",
      "rawMarkdown": "",
      "votes": null
    },
    {
      "id": "62834",
      "postDate": "01/17/2015 16:26:26",
      "content": "<p>See Nagadomi's post in this thread</p>\n\n<p>http://www.kaggle.com/c/datasciencebowl/forums/t/11421/converting-images-to-standard-scale-code</p>\n\n<p>for his approach to data augmentation.</p>",
      "rawMarkdown": "",
      "votes": null
    },
    {
      "id": "62839",
      "postDate": "01/17/2015 18:01:42",
      "content": "<p>Mike,&nbsp;<br><br>I recommend checking out this course:&nbsp;https://class.coursera.org/neuralnets-2012-001/lecture (Hopefully you can still audit the lectures)&nbsp;<br><br>Geoffrey Hinton covers combining models in lecture 10.<br><br>Here are the slides from that lecture in case you are unable to access the course material:&nbsp;https://d396qusza40orc.cloudfront.net/neuralnets/lecture_slides/lec10.pdf</p>\n<p>Regarding image augmentation, I built some&nbsp;basic augmentation tools in python using the <a href=\"https://pillow.readthedocs.org/\">Pillow</a>&nbsp;image processing library. When I have some spare time, I'll refactor my code and post it on the forums.&nbsp;</p>",
      "rawMarkdown": "",
      "votes": null
    },
    {
      "id": "62852",
      "postDate": "01/18/2015 06:02:46",
      "content": "<p>deep architecture with large input image(&gt;= 80x80) helps quite a bit.</p>\n<p>In my CNN, the size of input image is 1x96x96.</p>",
      "rawMarkdown": "",
      "votes": null
    },
    {
      "id": "62858",
      "postDate": "01/18/2015 13:54:51",
      "content": "<p>[quote=nagadomi;62852]</p>\n<p>deep architecture with large input image(&gt;= 80x80) helps quite a bit.</p>\n<p>In my CNN, the size of input image is 1x96x96.</p>\n<p>[/quote]</p>\n<p>Do you preserve aspect ratio? I found that if you break aspect ratio then you can work with smaller resolution.</p>",
      "rawMarkdown": "",
      "votes": null
    },
    {
      "id": "62867",
      "postDate": "01/18/2015 17:09:58",
      "content": "<p>[quote=Ilya Kostrikov;62858]</p>\n<p>[quote=nagadomi;62852]</p>\n<p>deep architecture with large input image(&gt;= 80x80) helps quite a bit.</p>\n<p>In my CNN, the size of input image is 1x96x96.</p>\n<p>[/quote]</p>\n<p>Do you preserve aspect ratio? I found that if you break aspect ratio then you can work with smaller resolution.</p>\n<p>[/quote]</p>\n<p>wow, that is very useful.<br>I had thought that top-20 people preserve aspect ratio.</p>\n<p>EDIT: In preprocessing, I preserve aspect ratio. but my data augmentation layer sometimes breaks aspect ratio.</p>",
      "rawMarkdown": "",
      "votes": null
    },
    {
      "id": "62870",
      "postDate": "01/18/2015 17:49:16",
      "content": "<p>Likewise, I've always blindly gone and preserved aspect ratio in preprocessing.<br><br>Thanks for the tip&nbsp;Ilya!</p>",
      "rawMarkdown": "",
      "votes": null
    },
    {
      "id": "62978",
      "postDate": "01/21/2015 20:26:55",
      "content": "<p>I'm quite surprised too. &nbsp;I thought people preserve aspect ratio...or else it might hurt performance..</p>\n<p>[quote=Ilya Kostrikov;62858]</p>\n<p>[quote=nagadomi;62852]</p>\n<p>deep architecture with large input image(&gt;= 80x80) helps quite a bit.</p>\n<p>In my CNN, the size of input image is 1x96x96.</p>\n<p>[/quote]</p>\n<p>Do you preserve aspect ratio? I found that if you break aspect ratio then you can work with smaller resolution.</p>\n<p>[/quote]</p>",
      "rawMarkdown": "",
      "votes": null
    },
    {
      "id": "62990",
      "postDate": "01/22/2015 01:21:22",
      "content": "<p>My best score (1.18 or so on the leaderboard) was with 48x48 sized images, just straight resized (and thus breaking aspect ratio). I have since run many, many more configurations with 94x94 and 96x96 aditional layers, different number of nodes, etc. while&nbsp;<em>preserving&nbsp;</em>aspect ratio (rotate 45 degrees, 90 degrees, flip vertical and flip horizontal, while trying also to &quot;balance out&quot; the data set across classes), and to my surprise have never surpassed&nbsp;my &quot;dumb&quot; resize score. The best I got was an improved validation score, but it came out substantially higher on the public leaderboard (1.3, instead of the 1.14 my&nbsp;validation score suggested).</p>\n\n<p>Very counter-intuitive to me, as I had expected the more pixel resolution, the more refined details I could pick up on, but to be fair, I am learning as I go along with this... &nbsp;</p>",
      "rawMarkdown": "",
      "votes": null
    },
    {
      "id": "62991",
      "postDate": "01/22/2015 01:27:26",
      "content": "<p>Just resizing to 48x48 and then rotating 0/90/180/270 and mirroring should get you to a better lb score than that. I would&nbsp;check the generated images carefully and make sure there is not some mistake.</p>\n<p>Your 1.18 is very close to my best lb score at 48x48 with only a random mirror.</p>",
      "rawMarkdown": "",
      "votes": null
    },
    {
      "id": "62992",
      "postDate": "01/22/2015 01:49:59",
      "content": "<p>Can someone please confirm that my understanding of data augmentation is correct.&nbsp;Let assumes that we have 1 simple transformation of randomly rotating by 0/90/180/270 degrees and we have a total of 15 batches and 10 epochs.&nbsp;</p>\n<p>During training, for each batch in each epoch, we randomly rotate that batch of data and proceed&nbsp;with calculating the training and validation loss based on that augmentation. Therefore, every batch in every epoch will have a random data augmentation step applied to it.</p>\n<p>Thanks!</p>",
      "rawMarkdown": "",
      "votes": null
    },
    {
      "id": "62999",
      "postDate": "01/22/2015 09:51:17",
      "content": "<p>[quote=mike1886;62992]</p>\n<p>Can someone please confirm that my understanding of data augmentation is correct.&nbsp;Let assumes that we have 1 simple transformation of randomly rotating by 0/90/180/270 degrees and we have a total of 15 batches and 10 epochs.&nbsp;</p>\n<p>During training, for each batch in each epoch, we randomly rotate that batch of data and proceed&nbsp;with calculating the training and validation loss based on that augmentation. Therefore, every batch in every epoch will have a random data augmentation step applied to it.</p>\n<p>[/quote]</p>\n<p>That is one of many possible schemes, and I think it has a reasonable chance of improving the generalisation of any model capable of over-fitting.</p>\n<p>The general idea is to pick alterations to the input&nbsp;data that logically should not change the output class, and that remain representative of inputs you might expect to see in the test data.</p>\n<p>You have a few choices on how you then apply those alterations. With your scheme, as well as randomly altering items in each batch, you could pre-calculate all transformations and quadruple the size of your training set. If you had a scheme with more options, this is less feasible, but you could still just randomly generate a fixed training set size.&nbsp;Or you could effectively create an infinite online or semi-online data source, drawing from it on-demand.</p>",
      "rawMarkdown": "",
      "votes": null
    },
    {
      "id": "63003",
      "postDate": "01/22/2015 13:43:06",
      "content": "<p>thanks Neil that was very helpful!</p>\n<p>For the scheme I described, do you tend to leave a larger portion of the batches untransformed?&nbsp;</p>",
      "rawMarkdown": "",
      "votes": null
    },
    {
      "id": "63004",
      "postDate": "01/22/2015 13:55:00",
      "content": "<p>[quote=mike1886;63003]</p>\n<p>thanks Neil that was very helpful!</p>\n<p>For the scheme I described, do you tend to leave a larger portion of the batches untransformed?&nbsp;</p>\n<p>[/quote]</p>\n<p>I am not sure. My personal preference is to add the transforms (including a chance of no transform) to all inputs.&nbsp;However,&nbsp;I have no measure of whether that works in general. I haven't entered this competition, I'm just in the forums trying to learn more about CNNs.</p>",
      "rawMarkdown": "",
      "votes": null
    },
    {
      "id": "63022",
      "postDate": "01/22/2015 19:16:15",
      "content": "<p>[quote=James King;62991]</p>\n<p>Just resizing to 48x48 and then rotating 0/90/180/270 and mirroring should get you to a better lb score than that. I would&nbsp;check the generated images carefully and make sure there is not some mistake.</p>\n<p>Your 1.18 is very close to my best lb score at 48x48 with only a random mirror.</p>\n<p>[/quote]</p>\n<p>Thanks! I'll give that a try as well.</p>\n<p>I am printing out test images (one for each class on data load), and they come out just fine. I am still running further tests on my net architecture (next up is trying 5x5 filters, rather than 3x3) and with the larger images sizes I have been &quot;squaring&quot; them by creating a blank image of width and height based on max(org_img.width, org_img.height), which preserves aspect ratio, as well as a 45 degree transform, expanding the size, which creates a square image, as well. I'll have to try to go back to the straight resize, aspect ratio be damned! :)</p>\n<p>I am also suspecting now that selectively doing more data augmentation for those classes with fewer source images may actually be the wrong strategy...</p>\n<p>No test is wasted, though, as it is all an excellent exercise to see how this all works.&nbsp;</p>",
      "rawMarkdown": "",
      "votes": null
    },
    {
      "id": "63028",
      "postDate": "01/22/2015 19:41:51",
      "content": "<p>Is there a theoretical preferred way to combine real time augmentation (i.e. I feed 30k images into the network and flip them randomly at each epoch) and just increasing the size of the data by feeding more observation into the network (say I flip at 90, 180, 270 degrees, and feed 120k observations into the network)? Obviously the practical part is important, given the limited amount of GPU memory. Just curious to know what people is&nbsp;doing...</p>",
      "rawMarkdown": "",
      "votes": null
    },
    {
      "id": "63035",
      "postDate": "01/22/2015 22:16:28",
      "content": "<p>[quote=Giulio;63028]</p>\n<p>Is there a theoretical preferred way to combine real time augmentation (i.e. I feed 30k images into the network and flip them randomly at each epoch) and just increasing the size of the data by feeding more observation into the network (say I flip at 90, 180, 270 degrees, and feed 120k observations into the network)? Obviously the practical part is important, given the limited amount of GPU memory. Just curious to know what people is&nbsp;doing...</p>\n<p>[/quote]</p>\n<p>Real-time or online augmentation doesn't affect the GPU RAM requirement for SGD. It is because SGD is online learning. The RAM requirement is mainly determined by the model's total parameters and the mini-batch size.</p>",
      "rawMarkdown": "",
      "votes": null
    },
    {
      "id": "63036",
      "postDate": "01/23/2015 01:38:38",
      "content": "<p>How many epochs are people using?&nbsp;</p>\n<p>I am currently only using ~200-300 and using early stopping after 50 epochs of no improvement. However, I feel like I probably can let it run longer since it still doesn't seem to converge.&nbsp;</p>",
      "rawMarkdown": "",
      "votes": null
    },
    {
      "id": "63037",
      "postDate": "01/23/2015 02:43:21",
      "content": "<p>Here's the code I'm currently using to create the rotations of images.&nbsp;</p>\n<p>It's nothing special, and could probably use some cleanup, but it gets the job done.&nbsp;</p>\n<p>http://pastebin.com/SjTKUBGZ</p>\n<p>It's written in python. The only extra library needed is the Pillow library. You can install that if you have pip:</p>\n<p>```<br>pip install Pillow<br>```</p>\n<p>To use the code, all you need to do is pass a regular expression to the directory holding the images. The script will&nbsp;create image rotations at angles&nbsp;[45, 90, 135, 180, 225, 270, 315]. You can easily change this by modifying the rotation_angles variable.</p>\n<p>The output data will be written in the same directory with a _rot[angle].png suffix.&nbsp;</p>\n<p>I have some more augmentation code to share, I just haven't had much time to clean up my code.&nbsp;<br><br>Usage example:<br><br>python ./rotate_images.py ~/kaggle/plankton/data/train/\\*\\*.png<br><br>This will recursively rotate all images that match the wildcard expression.&nbsp;</p>",
      "rawMarkdown": "",
      "votes": null
    },
    {
      "id": "63128",
      "postDate": "01/25/2015 06:19:28",
      "content": "<p>Do you guys mind sharing how deep and wide are your&nbsp;fully connected layers? The CXXNET example uses 2 layers of 512 units and I feel that's not enough for 121 classes?</p>\n<p>Also what are your techniques to optimize the structure of the CNN? I tried visualizing the convolutional layer but it's not really useful (as it is so small).</p>",
      "rawMarkdown": "",
      "votes": null
    },
    {
      "id": "63142",
      "postDate": "01/25/2015 15:23:16",
      "content": "<p>My best results so far have come with&nbsp;</p>\n<p><span style=\"font-size: 15.5555562973022px; line-height: 1.4;\"> InputLayer (None, 1, 48, 48) produces 2304 outputs<br> Conv2DCCLayer (None, 192, 43, 43) produces 355008 outputs<br> MaxPool2DCCLayer (None, 192, 22, 22) produces 92928 outputs<br> DropoutLayer (None, 192, 22, 22) produces 92928 outputs<br> Conv2DCCLayer (None, 384, 18, 18) produces 124416 outputs<br> MaxPool2DCCLayer (None, 384, 9, 9) produces 31104 outputs<br> DropoutLayer (None, 384, 9, 9) produces 31104 outputs<br> DenseLayer (None, 1000) produces 1000 outputs<br> DropoutLayer (None, 1000) produces 1000 outputs<br> DenseLayer (None, 1000) produces 1000 outputs<br> DenseLayer (None, 121) produces 121 outputs</span></p>\n\n<p>I have also tried adding in a third Conv2DCCLayer and also a DropoutLayer after my last DenseLayer but that seems to not help. I <strong>think&nbsp;</strong>I need to increase my layer size to something bigger than 192 and 384 but not sure.&nbsp;</p>\n<p>What have you tried?</p>",
      "rawMarkdown": "",
      "votes": null
    },
    {
      "id": "63145",
      "postDate": "01/25/2015 16:27:12",
      "content": "<p>Ahh fellow nolearn user! I tried adding a 3rd convolutional layer too but I don't think it's helping. One thing that frustrates me is I don't know how to qualitatively compares 2 models. I tried visualizing the weights learned from the filter but it's hard to interpret.</p>\n<p>Now I'm trying out maxout layers (layers.FeaturePoolLayer) (see&nbsp;http://arxiv.org/pdf/1302.4389v4.pdf) and debugging my&nbsp;batch iterator to make sure the data augmentation is working properly.</p>",
      "rawMarkdown": "",
      "votes": null
    },
    {
      "id": "63149",
      "postDate": "01/25/2015 18:10:45",
      "content": "<p>Have you experimented with different dropout values? I found that 0.5 seems to work best but didn't try to many values or scenarios?</p>",
      "rawMarkdown": "",
      "votes": null
    },
    {
      "id": "63151",
      "postDate": "01/25/2015 19:02:24",
      "content": "<p>I just submitted a 1.08 score with:</p>\n\n<p>Input: 60x60</p>\n<p>L1 weights: 1 x 32 x 5x5 convolution</p>\n<p>maxpool</p>\n<p>L2 weights: 32 x 64 x 5x5 convolution</p>\n<p>maxpool</p>\n<p>L3 weights: 64 x 128 x 5x5 convolution</p>\n<p>maxpool</p>\n<p>flatten</p>\n<p>L4: 128x4x4 x 2025</p>\n<p>L5: 2025 x 121 (softmax)</p>\n<p>Dropout hidden: 0.5, dropout convolution: 0.2</p>\n<p>Batch sizes of 512, learning rate of 0.001 with RMSProp; training source images rotated 45 degrees, then all 90 degrees, then all 180 degrees.</p>\n<p>I tried higher dropout values, but it just slows learning down dramatically. </p>",
      "rawMarkdown": "",
      "votes": null
    },
    {
      "id": "63163",
      "postDate": "01/25/2015 21:37:47",
      "content": "<p>[quote=Jay Thoden van Velzen;63151]</p>\n<p>I just submitted a 1.08 score with:</p>\n<p>Input: 60x60</p>\n<p>L1 weights: 1 x 32 x 5x5 convolution</p>\n<p>maxpool</p>\n<p>L2 weights: 32 x 64 x 5x5 convolution</p>\n<p>maxpool</p>\n<p>L3 weights: 64 x 128 x 5x5 convolution</p>\n<p>maxpool</p>\n<p>flatten</p>\n<p>L4: 128x4x4 x 2025</p>\n<p>L5: 2025 x 121 (softmax)</p>\n<p>Dropout hidden: 0.5, dropout convolution: 0.2</p>\n<p>Batch sizes of 512, learning rate of 0.001 with RMSProp; training source images rotated 45 degrees, then all 90 degrees, then all 180 degrees.</p>\n<p>I tried higher dropout values, but it just slows learning down dramatically.</p>\n<p>[/quote]<br><br>Maybe my implementation of RMSProp is incorrect, but I was unable to get RMSProp to work very well.&nbsp;</p>",
      "rawMarkdown": "",
      "votes": null
    },
    {
      "id": "63164",
      "postDate": "01/25/2015 21:51:47",
      "content": "<p>Miroslaw, can you&nbsp;provide a reference for RMSProp, I would like to try it out. Thanks!</p>",
      "rawMarkdown": "",
      "votes": null
    },
    {
      "id": "63394",
      "postDate": "01/31/2015 18:46:41",
      "content": "<p>Here is my RMSProp function, as well as one with Nesterov momentum (though that didn't give me better results):</p>\n\n<p><code>def RMSprop(cost, params, lr=0.001, rho=0.9, epsilon=1e-6):<br>&nbsp;grads = T.grad(cost=cost, wrt=params)<br>&nbsp;updates = []<br>&nbsp;for p, g in zip(params, grads):<br>&nbsp; acc = theano.shared(p.get_value() * 0.)<br>&nbsp; acc_new = rho * acc + (1 - rho) * g ** 2<br>&nbsp; gradient_scaling = T.sqrt(acc_new + epsilon)<br>&nbsp; g = g / gradient_scaling<br>&nbsp; updates.append((acc, acc_new))<br>&nbsp; updates.append((p, p - lr * g))</code></p>\n<p><code>&nbsp;return updates</code></p>\n<p><code>def RMSprop_nesterov(cost, params, lr=0.001, rho=0.9, momentum=0.7, epsilon=1e-6):<br>&nbsp; grads = T.grad(cost=cost, wrt=params)<br>&nbsp; updates = []<br>&nbsp; for p, g in zip(params, grads):<br>&nbsp;&nbsp; mo_p = theano.shared(p.get_value() * 0.)<br>&nbsp;&nbsp; acc = theano.shared(p.get_value() * 0.)<br>&nbsp;&nbsp; acc_new = rho * acc + (1 - rho) * g**2</code><code>step = lr * g / T.sqrt(acc_new + epsilon)<br>&nbsp;&nbsp; v = momentum * mo_p - step<br>&nbsp;&nbsp; w_ = p + momentum * v - step<br>&nbsp;&nbsp; updates.append((acc, acc_new))<br>&nbsp;&nbsp; updates.append((mo_p, v))<br>&nbsp;&nbsp; updates.append((p, w_))<br>&nbsp;return updates</code></p>",
      "rawMarkdown": "",
      "votes": null
    }
  ],
  "comments": [
    {
      "id": 62801,
      "author_name": "jfkingiii",
      "author_url": "",
      "post_date": "01/16/2015 20:25:41",
      "content": "<p>You can share within a team or share on the forum, but it is against the rules to bounce ideas off of each other in email unless you are on the same team.</p>",
      "votes": null,
      "replies": []
    },
    {
      "id": 62802,
      "author_name": "msegala",
      "author_url": "",
      "post_date": "01/16/2015 20:31:48",
      "content": "<p>Sorry, I did not know that. &nbsp;I guess I then withdraw this forum post.&nbsp;</p>",
      "votes": null,
      "replies": []
    },
    {
      "id": 62807,
      "author_name": "miroslaw",
      "author_url": "",
      "post_date": "01/17/2015 00:09:56",
      "content": "<p>James,&nbsp;<br><br>Where does it specifically say we are unable to share ideas privately? I only see rules for code.&nbsp;<br><br>How are people supposed to team up without sharing any ideas prior? Seems like a poor strategy to blindly team up with another competitor with no insight into their methodology.&nbsp;</p>",
      "votes": null,
      "replies": []
    },
    {
      "id": 62809,
      "author_name": "jfkingiii",
      "author_url": "",
      "post_date": "01/17/2015 01:03:49",
      "content": "<p>It's true the rules only refer to sharing code and data, which strikes me as strange since in most competitions you could easily describe your whole approach in an easy to replicate way without sharing any code or data. If someone describes their entire convnet architecture and data augmentation scheme, that's just as good as sharing the code.</p>\n\n<p>As far as blindly teaming up with no insight into each other's methodology, that's how I've always done it.</p>",
      "votes": null,
      "replies": []
    },
    {
      "id": 62810,
      "author_name": "msegala",
      "author_url": "",
      "post_date": "01/17/2015 02:51:52",
      "content": "<p>To stay within the rules I don't mind having the conversation here. Basically I am interested in which architecture&nbsp;people are using to train their CNNs. I am currently using a pure theano approach (similar to this <a href=\"http://www.deeplearning.net/tutorial/lenet.html#lenet\">theano CNN</a>) but cannot seem to break the 1.2 barrier in my error score.&nbsp;</p>\n<p>Are people using (or have used in the past) any &quot;black box&quot; architectures such as Caffe or cuda-ConvNet2, or any others?</p>\n<p>Considering I am still&nbsp;getting a score about twice that of the leading scores right now I am keen tp try some new approaches.&nbsp;</p>",
      "votes": null,
      "replies": []
    },
    {
      "id": 62811,
      "author_name": "jfkingiii",
      "author_url": "",
      "post_date": "01/17/2015 03:53:38",
      "content": "<p>I started with the cxxnet kaggle bowl example and built on that. It's not a very complex architecture, so I had to beef it up a bit. Data augmentation helps quite a bit.</p>",
      "votes": null,
      "replies": []
    },
    {
      "id": 62823,
      "author_name": "miroslaw",
      "author_url": "",
      "post_date": "01/17/2015 09:54:48",
      "content": "<p>James, that's quite impressive that you blindly team up with people without sharing strategies prior. I doubt many other competitors do the same (especially in late game). It'd be interesting to see how effective that strategy is in practice.&nbsp;</p>\n<p>How would a rule on sharing ideas privately even be enforced?&nbsp;<br><br>From my experience with past kaggle competitions, there's always been sharing of ideas between competitors in private. Heck, I speak to competitors in private about ideas without the intention to compete myself.&nbsp;<br><br>In my opinion, there's a big difference between sharing strategies that may help a fellow competitor improve their skills as a data scientist, and giving away a winning strategy. (Hell, if you have a winning strategy, why would you share it in the first place?). If someone takes the time to show that they have a willingness to learn by asking questions to fellow competitors in private, then I have no qualms with helping as much as I can. I feel it's ridiculous to impose the constraint that those ideas must be made public.<br><br>Anyway, Mike, while I have not made a submission yet, I've had decent&nbsp;results with building an augmented dataset of the training data (CV results are ~0.9-1.09 log-loss) with a simple 2 layer CNN (100, 150 filters with max pooling) with a 500-121 hidden unit dense layer with a softmax classifier.<br><br>Augmentation of the dataset includes: random rotation (between 0-360), random cropping, and random mirroring.&nbsp;</p>",
      "votes": null,
      "replies": []
    },
    {
      "id": 62829,
      "author_name": "msegala",
      "author_url": "",
      "post_date": "01/17/2015 14:16:56",
      "content": "<p>Miroslaw,</p>\n<p>Thanks for the info. I think one of my big problems is I do no data augmentation, I just take the raw pixels as is and feed that to my net. Can you explain a bit on how to do this properly or point me to some references that go through it in detail.&nbsp;</p>\n<p>Also, I have seen winning solutions in other image classification competitions (<a href=\"https://github.com/benanne/kaggle-galaxies\">kaggle-galaxies</a>) blend multiple models together. Do you have a good idea of what they are doing here?</p>\n<p>Thanks!</p>",
      "votes": null,
      "replies": []
    },
    {
      "id": 62834,
      "author_name": "jfkingiii",
      "author_url": "",
      "post_date": "01/17/2015 16:26:26",
      "content": "<p>See Nagadomi's post in this thread</p>\n\n<p>http://www.kaggle.com/c/datasciencebowl/forums/t/11421/converting-images-to-standard-scale-code</p>\n\n<p>for his approach to data augmentation.</p>",
      "votes": null,
      "replies": []
    },
    {
      "id": 62839,
      "author_name": "miroslaw",
      "author_url": "",
      "post_date": "01/17/2015 18:01:42",
      "content": "<p>Mike,&nbsp;<br><br>I recommend checking out this course:&nbsp;https://class.coursera.org/neuralnets-2012-001/lecture (Hopefully you can still audit the lectures)&nbsp;<br><br>Geoffrey Hinton covers combining models in lecture 10.<br><br>Here are the slides from that lecture in case you are unable to access the course material:&nbsp;https://d396qusza40orc.cloudfront.net/neuralnets/lecture_slides/lec10.pdf</p>\n<p>Regarding image augmentation, I built some&nbsp;basic augmentation tools in python using the <a href=\"https://pillow.readthedocs.org/\">Pillow</a>&nbsp;image processing library. When I have some spare time, I'll refactor my code and post it on the forums.&nbsp;</p>",
      "votes": null,
      "replies": []
    },
    {
      "id": 62852,
      "author_name": "nagadomi",
      "author_url": "",
      "post_date": "01/18/2015 06:02:46",
      "content": "<p>deep architecture with large input image(&gt;= 80x80) helps quite a bit.</p>\n<p>In my CNN, the size of input image is 1x96x96.</p>",
      "votes": null,
      "replies": []
    },
    {
      "id": 62858,
      "author_name": "ilyakostrikov",
      "author_url": "",
      "post_date": "01/18/2015 13:54:51",
      "content": "<p>[quote=nagadomi;62852]</p>\n<p>deep architecture with large input image(&gt;= 80x80) helps quite a bit.</p>\n<p>In my CNN, the size of input image is 1x96x96.</p>\n<p>[/quote]</p>\n<p>Do you preserve aspect ratio? I found that if you break aspect ratio then you can work with smaller resolution.</p>",
      "votes": null,
      "replies": []
    },
    {
      "id": 62867,
      "author_name": "nagadomi",
      "author_url": "",
      "post_date": "01/18/2015 17:09:58",
      "content": "<p>[quote=Ilya Kostrikov;62858]</p>\n<p>[quote=nagadomi;62852]</p>\n<p>deep architecture with large input image(&gt;= 80x80) helps quite a bit.</p>\n<p>In my CNN, the size of input image is 1x96x96.</p>\n<p>[/quote]</p>\n<p>Do you preserve aspect ratio? I found that if you break aspect ratio then you can work with smaller resolution.</p>\n<p>[/quote]</p>\n<p>wow, that is very useful.<br>I had thought that top-20 people preserve aspect ratio.</p>\n<p>EDIT: In preprocessing, I preserve aspect ratio. but my data augmentation layer sometimes breaks aspect ratio.</p>",
      "votes": null,
      "replies": []
    },
    {
      "id": 62870,
      "author_name": "miroslaw",
      "author_url": "",
      "post_date": "01/18/2015 17:49:16",
      "content": "<p>Likewise, I've always blindly gone and preserved aspect ratio in preprocessing.<br><br>Thanks for the tip&nbsp;Ilya!</p>",
      "votes": null,
      "replies": []
    },
    {
      "id": 62978,
      "author_name": "woshialex",
      "author_url": "",
      "post_date": "01/21/2015 20:26:55",
      "content": "<p>I'm quite surprised too. &nbsp;I thought people preserve aspect ratio...or else it might hurt performance..</p>\n<p>[quote=Ilya Kostrikov;62858]</p>\n<p>[quote=nagadomi;62852]</p>\n<p>deep architecture with large input image(&gt;= 80x80) helps quite a bit.</p>\n<p>In my CNN, the size of input image is 1x96x96.</p>\n<p>[/quote]</p>\n<p>Do you preserve aspect ratio? I found that if you break aspect ratio then you can work with smaller resolution.</p>\n<p>[/quote]</p>",
      "votes": null,
      "replies": []
    },
    {
      "id": 62990,
      "author_name": "jaythodenvanvelzen",
      "author_url": "",
      "post_date": "01/22/2015 01:21:22",
      "content": "<p>My best score (1.18 or so on the leaderboard) was with 48x48 sized images, just straight resized (and thus breaking aspect ratio). I have since run many, many more configurations with 94x94 and 96x96 aditional layers, different number of nodes, etc. while&nbsp;<em>preserving&nbsp;</em>aspect ratio (rotate 45 degrees, 90 degrees, flip vertical and flip horizontal, while trying also to &quot;balance out&quot; the data set across classes), and to my surprise have never surpassed&nbsp;my &quot;dumb&quot; resize score. The best I got was an improved validation score, but it came out substantially higher on the public leaderboard (1.3, instead of the 1.14 my&nbsp;validation score suggested).</p>\n\n<p>Very counter-intuitive to me, as I had expected the more pixel resolution, the more refined details I could pick up on, but to be fair, I am learning as I go along with this... &nbsp;</p>",
      "votes": null,
      "replies": []
    },
    {
      "id": 62991,
      "author_name": "jfkingiii",
      "author_url": "",
      "post_date": "01/22/2015 01:27:26",
      "content": "<p>Just resizing to 48x48 and then rotating 0/90/180/270 and mirroring should get you to a better lb score than that. I would&nbsp;check the generated images carefully and make sure there is not some mistake.</p>\n<p>Your 1.18 is very close to my best lb score at 48x48 with only a random mirror.</p>",
      "votes": null,
      "replies": []
    },
    {
      "id": 62992,
      "author_name": "msegala",
      "author_url": "",
      "post_date": "01/22/2015 01:49:59",
      "content": "<p>Can someone please confirm that my understanding of data augmentation is correct.&nbsp;Let assumes that we have 1 simple transformation of randomly rotating by 0/90/180/270 degrees and we have a total of 15 batches and 10 epochs.&nbsp;</p>\n<p>During training, for each batch in each epoch, we randomly rotate that batch of data and proceed&nbsp;with calculating the training and validation loss based on that augmentation. Therefore, every batch in every epoch will have a random data augmentation step applied to it.</p>\n<p>Thanks!</p>",
      "votes": null,
      "replies": []
    },
    {
      "id": 62999,
      "author_name": "slobo777",
      "author_url": "",
      "post_date": "01/22/2015 09:51:17",
      "content": "<p>[quote=mike1886;62992]</p>\n<p>Can someone please confirm that my understanding of data augmentation is correct.&nbsp;Let assumes that we have 1 simple transformation of randomly rotating by 0/90/180/270 degrees and we have a total of 15 batches and 10 epochs.&nbsp;</p>\n<p>During training, for each batch in each epoch, we randomly rotate that batch of data and proceed&nbsp;with calculating the training and validation loss based on that augmentation. Therefore, every batch in every epoch will have a random data augmentation step applied to it.</p>\n<p>[/quote]</p>\n<p>That is one of many possible schemes, and I think it has a reasonable chance of improving the generalisation of any model capable of over-fitting.</p>\n<p>The general idea is to pick alterations to the input&nbsp;data that logically should not change the output class, and that remain representative of inputs you might expect to see in the test data.</p>\n<p>You have a few choices on how you then apply those alterations. With your scheme, as well as randomly altering items in each batch, you could pre-calculate all transformations and quadruple the size of your training set. If you had a scheme with more options, this is less feasible, but you could still just randomly generate a fixed training set size.&nbsp;Or you could effectively create an infinite online or semi-online data source, drawing from it on-demand.</p>",
      "votes": null,
      "replies": []
    },
    {
      "id": 63003,
      "author_name": "msegala",
      "author_url": "",
      "post_date": "01/22/2015 13:43:06",
      "content": "<p>thanks Neil that was very helpful!</p>\n<p>For the scheme I described, do you tend to leave a larger portion of the batches untransformed?&nbsp;</p>",
      "votes": null,
      "replies": []
    },
    {
      "id": 63004,
      "author_name": "slobo777",
      "author_url": "",
      "post_date": "01/22/2015 13:55:00",
      "content": "<p>[quote=mike1886;63003]</p>\n<p>thanks Neil that was very helpful!</p>\n<p>For the scheme I described, do you tend to leave a larger portion of the batches untransformed?&nbsp;</p>\n<p>[/quote]</p>\n<p>I am not sure. My personal preference is to add the transforms (including a chance of no transform) to all inputs.&nbsp;However,&nbsp;I have no measure of whether that works in general. I haven't entered this competition, I'm just in the forums trying to learn more about CNNs.</p>",
      "votes": null,
      "replies": []
    },
    {
      "id": 63022,
      "author_name": "jaythodenvanvelzen",
      "author_url": "",
      "post_date": "01/22/2015 19:16:15",
      "content": "<p>[quote=James King;62991]</p>\n<p>Just resizing to 48x48 and then rotating 0/90/180/270 and mirroring should get you to a better lb score than that. I would&nbsp;check the generated images carefully and make sure there is not some mistake.</p>\n<p>Your 1.18 is very close to my best lb score at 48x48 with only a random mirror.</p>\n<p>[/quote]</p>\n<p>Thanks! I'll give that a try as well.</p>\n<p>I am printing out test images (one for each class on data load), and they come out just fine. I am still running further tests on my net architecture (next up is trying 5x5 filters, rather than 3x3) and with the larger images sizes I have been &quot;squaring&quot; them by creating a blank image of width and height based on max(org_img.width, org_img.height), which preserves aspect ratio, as well as a 45 degree transform, expanding the size, which creates a square image, as well. I'll have to try to go back to the straight resize, aspect ratio be damned! :)</p>\n<p>I am also suspecting now that selectively doing more data augmentation for those classes with fewer source images may actually be the wrong strategy...</p>\n<p>No test is wasted, though, as it is all an excellent exercise to see how this all works.&nbsp;</p>",
      "votes": null,
      "replies": []
    },
    {
      "id": 63028,
      "author_name": "adjgiulio",
      "author_url": "",
      "post_date": "01/22/2015 19:41:51",
      "content": "<p>Is there a theoretical preferred way to combine real time augmentation (i.e. I feed 30k images into the network and flip them randomly at each epoch) and just increasing the size of the data by feeding more observation into the network (say I flip at 90, 180, 270 degrees, and feed 120k observations into the network)? Obviously the practical part is important, given the limited amount of GPU memory. Just curious to know what people is&nbsp;doing...</p>",
      "votes": null,
      "replies": []
    },
    {
      "id": 63035,
      "author_name": "songgc",
      "author_url": "",
      "post_date": "01/22/2015 22:16:28",
      "content": "<p>[quote=Giulio;63028]</p>\n<p>Is there a theoretical preferred way to combine real time augmentation (i.e. I feed 30k images into the network and flip them randomly at each epoch) and just increasing the size of the data by feeding more observation into the network (say I flip at 90, 180, 270 degrees, and feed 120k observations into the network)? Obviously the practical part is important, given the limited amount of GPU memory. Just curious to know what people is&nbsp;doing...</p>\n<p>[/quote]</p>\n<p>Real-time or online augmentation doesn't affect the GPU RAM requirement for SGD. It is because SGD is online learning. The RAM requirement is mainly determined by the model's total parameters and the mini-batch size.</p>",
      "votes": null,
      "replies": []
    },
    {
      "id": 63036,
      "author_name": "msegala",
      "author_url": "",
      "post_date": "01/23/2015 01:38:38",
      "content": "<p>How many epochs are people using?&nbsp;</p>\n<p>I am currently only using ~200-300 and using early stopping after 50 epochs of no improvement. However, I feel like I probably can let it run longer since it still doesn't seem to converge.&nbsp;</p>",
      "votes": null,
      "replies": []
    },
    {
      "id": 63037,
      "author_name": "miroslaw",
      "author_url": "",
      "post_date": "01/23/2015 02:43:21",
      "content": "<p>Here's the code I'm currently using to create the rotations of images.&nbsp;</p>\n<p>It's nothing special, and could probably use some cleanup, but it gets the job done.&nbsp;</p>\n<p>http://pastebin.com/SjTKUBGZ</p>\n<p>It's written in python. The only extra library needed is the Pillow library. You can install that if you have pip:</p>\n<p>```<br>pip install Pillow<br>```</p>\n<p>To use the code, all you need to do is pass a regular expression to the directory holding the images. The script will&nbsp;create image rotations at angles&nbsp;[45, 90, 135, 180, 225, 270, 315]. You can easily change this by modifying the rotation_angles variable.</p>\n<p>The output data will be written in the same directory with a _rot[angle].png suffix.&nbsp;</p>\n<p>I have some more augmentation code to share, I just haven't had much time to clean up my code.&nbsp;<br><br>Usage example:<br><br>python ./rotate_images.py ~/kaggle/plankton/data/train/\\*\\*.png<br><br>This will recursively rotate all images that match the wildcard expression.&nbsp;</p>",
      "votes": null,
      "replies": []
    },
    {
      "id": 63128,
      "author_name": "felixlaumon",
      "author_url": "",
      "post_date": "01/25/2015 06:19:28",
      "content": "<p>Do you guys mind sharing how deep and wide are your&nbsp;fully connected layers? The CXXNET example uses 2 layers of 512 units and I feel that's not enough for 121 classes?</p>\n<p>Also what are your techniques to optimize the structure of the CNN? I tried visualizing the convolutional layer but it's not really useful (as it is so small).</p>",
      "votes": null,
      "replies": []
    },
    {
      "id": 63142,
      "author_name": "msegala",
      "author_url": "",
      "post_date": "01/25/2015 15:23:16",
      "content": "<p>My best results so far have come with&nbsp;</p>\n<p><span style=\"font-size: 15.5555562973022px; line-height: 1.4;\"> InputLayer (None, 1, 48, 48) produces 2304 outputs<br> Conv2DCCLayer (None, 192, 43, 43) produces 355008 outputs<br> MaxPool2DCCLayer (None, 192, 22, 22) produces 92928 outputs<br> DropoutLayer (None, 192, 22, 22) produces 92928 outputs<br> Conv2DCCLayer (None, 384, 18, 18) produces 124416 outputs<br> MaxPool2DCCLayer (None, 384, 9, 9) produces 31104 outputs<br> DropoutLayer (None, 384, 9, 9) produces 31104 outputs<br> DenseLayer (None, 1000) produces 1000 outputs<br> DropoutLayer (None, 1000) produces 1000 outputs<br> DenseLayer (None, 1000) produces 1000 outputs<br> DenseLayer (None, 121) produces 121 outputs</span></p>\n\n<p>I have also tried adding in a third Conv2DCCLayer and also a DropoutLayer after my last DenseLayer but that seems to not help. I <strong>think&nbsp;</strong>I need to increase my layer size to something bigger than 192 and 384 but not sure.&nbsp;</p>\n<p>What have you tried?</p>",
      "votes": null,
      "replies": []
    },
    {
      "id": 63145,
      "author_name": "felixlaumon",
      "author_url": "",
      "post_date": "01/25/2015 16:27:12",
      "content": "<p>Ahh fellow nolearn user! I tried adding a 3rd convolutional layer too but I don't think it's helping. One thing that frustrates me is I don't know how to qualitatively compares 2 models. I tried visualizing the weights learned from the filter but it's hard to interpret.</p>\n<p>Now I'm trying out maxout layers (layers.FeaturePoolLayer) (see&nbsp;http://arxiv.org/pdf/1302.4389v4.pdf) and debugging my&nbsp;batch iterator to make sure the data augmentation is working properly.</p>",
      "votes": null,
      "replies": []
    },
    {
      "id": 63149,
      "author_name": "msegala",
      "author_url": "",
      "post_date": "01/25/2015 18:10:45",
      "content": "<p>Have you experimented with different dropout values? I found that 0.5 seems to work best but didn't try to many values or scenarios?</p>",
      "votes": null,
      "replies": []
    },
    {
      "id": 63151,
      "author_name": "jaythodenvanvelzen",
      "author_url": "",
      "post_date": "01/25/2015 19:02:24",
      "content": "<p>I just submitted a 1.08 score with:</p>\n\n<p>Input: 60x60</p>\n<p>L1 weights: 1 x 32 x 5x5 convolution</p>\n<p>maxpool</p>\n<p>L2 weights: 32 x 64 x 5x5 convolution</p>\n<p>maxpool</p>\n<p>L3 weights: 64 x 128 x 5x5 convolution</p>\n<p>maxpool</p>\n<p>flatten</p>\n<p>L4: 128x4x4 x 2025</p>\n<p>L5: 2025 x 121 (softmax)</p>\n<p>Dropout hidden: 0.5, dropout convolution: 0.2</p>\n<p>Batch sizes of 512, learning rate of 0.001 with RMSProp; training source images rotated 45 degrees, then all 90 degrees, then all 180 degrees.</p>\n<p>I tried higher dropout values, but it just slows learning down dramatically. </p>",
      "votes": null,
      "replies": []
    },
    {
      "id": 63163,
      "author_name": "miroslaw",
      "author_url": "",
      "post_date": "01/25/2015 21:37:47",
      "content": "<p>[quote=Jay Thoden van Velzen;63151]</p>\n<p>I just submitted a 1.08 score with:</p>\n<p>Input: 60x60</p>\n<p>L1 weights: 1 x 32 x 5x5 convolution</p>\n<p>maxpool</p>\n<p>L2 weights: 32 x 64 x 5x5 convolution</p>\n<p>maxpool</p>\n<p>L3 weights: 64 x 128 x 5x5 convolution</p>\n<p>maxpool</p>\n<p>flatten</p>\n<p>L4: 128x4x4 x 2025</p>\n<p>L5: 2025 x 121 (softmax)</p>\n<p>Dropout hidden: 0.5, dropout convolution: 0.2</p>\n<p>Batch sizes of 512, learning rate of 0.001 with RMSProp; training source images rotated 45 degrees, then all 90 degrees, then all 180 degrees.</p>\n<p>I tried higher dropout values, but it just slows learning down dramatically.</p>\n<p>[/quote]<br><br>Maybe my implementation of RMSProp is incorrect, but I was unable to get RMSProp to work very well.&nbsp;</p>",
      "votes": null,
      "replies": []
    },
    {
      "id": 63164,
      "author_name": "msegala",
      "author_url": "",
      "post_date": "01/25/2015 21:51:47",
      "content": "<p>Miroslaw, can you&nbsp;provide a reference for RMSProp, I would like to try it out. Thanks!</p>",
      "votes": null,
      "replies": []
    },
    {
      "id": 63394,
      "author_name": "jaythodenvanvelzen",
      "author_url": "",
      "post_date": "01/31/2015 18:46:41",
      "content": "<p>Here is my RMSProp function, as well as one with Nesterov momentum (though that didn't give me better results):</p>\n\n<p><code>def RMSprop(cost, params, lr=0.001, rho=0.9, epsilon=1e-6):<br>&nbsp;grads = T.grad(cost=cost, wrt=params)<br>&nbsp;updates = []<br>&nbsp;for p, g in zip(params, grads):<br>&nbsp; acc = theano.shared(p.get_value() * 0.)<br>&nbsp; acc_new = rho * acc + (1 - rho) * g ** 2<br>&nbsp; gradient_scaling = T.sqrt(acc_new + epsilon)<br>&nbsp; g = g / gradient_scaling<br>&nbsp; updates.append((acc, acc_new))<br>&nbsp; updates.append((p, p - lr * g))</code></p>\n<p><code>&nbsp;return updates</code></p>\n<p><code>def RMSprop_nesterov(cost, params, lr=0.001, rho=0.9, momentum=0.7, epsilon=1e-6):<br>&nbsp; grads = T.grad(cost=cost, wrt=params)<br>&nbsp; updates = []<br>&nbsp; for p, g in zip(params, grads):<br>&nbsp;&nbsp; mo_p = theano.shared(p.get_value() * 0.)<br>&nbsp;&nbsp; acc = theano.shared(p.get_value() * 0.)<br>&nbsp;&nbsp; acc_new = rho * acc + (1 - rho) * g**2</code><code>step = lr * g / T.sqrt(acc_new + epsilon)<br>&nbsp;&nbsp; v = momentum * mo_p - step<br>&nbsp;&nbsp; w_ = p + momentum * v - step<br>&nbsp;&nbsp; updates.append((acc, acc_new))<br>&nbsp;&nbsp; updates.append((mo_p, v))<br>&nbsp;&nbsp; updates.append((p, w_))<br>&nbsp;return updates</code></p>",
      "votes": null,
      "replies": []
    }
  ],
  "raw_markdown_by_id": {
    "62799": "",
    "62801": "",
    "62802": "",
    "62807": "",
    "62809": "",
    "62810": "",
    "62811": "",
    "62823": "",
    "62829": "",
    "62834": "",
    "62839": "",
    "62852": "",
    "62858": "",
    "62867": "",
    "62870": "",
    "62978": "",
    "62990": "",
    "62991": "",
    "62992": "",
    "62999": "",
    "63003": "",
    "63004": "",
    "63022": "",
    "63028": "",
    "63035": "",
    "63036": "",
    "63037": "",
    "63128": "",
    "63142": "",
    "63145": "",
    "63149": "",
    "63151": "",
    "63163": "",
    "63164": "",
    "63394": ""
  },
  "source": "meta"
}