import%20marimo%0A%0A__generated_with%20%3D%20%220.25.0%22%0Aapp%20%3D%20marimo.App()%0A%0A%0A%40app.cell(hide_code%3DTrue)%0Adef%20_()%3A%0A%20%20%20%20import%20marimo%20as%20mo%0A%0A%20%20%20%20return%20(mo%2C)%0A%0A%0A%40app.cell(hide_code%3DTrue)%0Adef%20_(mo)%3A%0A%20%20%20%20METADATA%20%3D%20%7B%0A%20%20%20%20%20%20%20%20%22id%22%3A%20%22convolution%22%2C%0A%20%20%20%20%20%20%20%20%22name%22%3A%20%22Convolution%22%2C%0A%20%20%20%20%20%20%20%20%22kind%22%3A%20%22concept%22%2C%0A%20%20%20%20%20%20%20%20%22difficulty%22%3A%20%22intermediate%22%2C%0A%20%20%20%20%20%20%20%20%22status%22%3A%20%22complete%22%2C%0A%20%20%20%20%20%20%20%20%22summary%22%3A%20%22Convolution%20slides%20a%20small%20filter%20across%20an%20image%20to%20produce%20a%20map%20showing%20where%20a%20local%20pattern%20appears.%22%2C%0A%20%20%20%20%20%20%20%20%22topics%22%3A%20%5B%22neural_networks%22%5D%2C%0A%20%20%20%20%20%20%20%20%22related_models%22%3A%20%5B%5D%2C%0A%20%20%20%20%20%20%20%20%22prerequisites%22%3A%20%5B%22perceptron%22%2C%20%22backpropagation%22%5D%2C%0A%20%20%20%20%7D%0A%20%20%20%20mo.md(f%22%23%20%7BMETADATA%5B'name'%5D%7D%22)%0A%20%20%20%20return%0A%0A%0A%40app.cell(hide_code%3DTrue)%0Adef%20_(mo)%3A%0A%20%20%20%20mo.md(r%22%22%22%0A%20%20%20%20%23%23%20In%20one%20sentence%0A%0A%20%20%20%20Convolution%20slides%20a%20small%20filter%20across%20an%20image%20to%20produce%20a%20map%20showing%20where%20a%20local%20pattern%20appears.%0A%0A%20%20%20%20%23%23%20Why%20not%20connect%20every%20pixel%20to%20every%20neuron%3F%0A%0A%20%20%20%20A%20%24224%5Ctimes224%5Ctimes3%24%20image%20already%20contains%20150%2C528%20values.%20A%20dense%20layer%20with%201%2C000%20neurons%20would%20have%20more%20than%20150%20million%20weights%20without%20using%20the%20fact%20that%20an%20edge%20is%20still%20an%20edge%20whether%20it%20appears%20on%20the%20left%20or%20right%20of%20the%20image.%0A%0A%20%20%20%20Convolution%20uses%20two%20natural%20assumptions%20about%20images%3A%0A%0A%20%20%20%20-%20**Locality**%3A%20a%20pixel%20is%20most%20closely%20related%20to%20its%20nearby%20neighbors.%0A%20%20%20%20-%20**Weight%20sharing**%3A%20the%20same%20pattern%20can%20appear%20anywhere.%0A%0A%20%20%20%20A%20filter%20(or%20*kernel*)%20is%20therefore%20a%20small%20grid%20of%20numbers%2C%20such%20as%20%243%5Ctimes3%24%2C%20that%20the%20network%20learns%20during%20training.%0A%20%20%20%20%22%22%22)%0A%20%20%20%20return%0A%0A%0A%40app.cell(hide_code%3DTrue)%0Adef%20_(mo)%3A%0A%20%20%20%20mo.md(r%22%22%22%0A%20%20%20%20%23%23%20Convolution%2C%20step%20by%20step%0A%0A%20%20%20%20Take%20a%20grayscale%20image%20%24X%24%20and%20a%20filter%20%24K%24.%20At%20a%20given%20position%2C%20place%20the%20filter%20over%20a%20small%20image%20window%2C%20multiply%20corresponding%20entries%2C%20then%20add%20them%20up%3A%0A%0A%20%20%20%20%24%24%0A%20%20%20%20Y_%7Bi%2Cj%7D%3Db%2B%5Csum_%7Bu%3D0%7D%5E%7Bk_h-1%7D%5Csum_%7Bv%3D0%7D%5E%7Bk_w-1%7D%20X_%7Bi%2Bu%2Cj%2Bv%7DK_%7Bu%2Cv%7D.%0A%20%20%20%20%24%24%0A%0A%20%20%20%20In%20practice%2C%20libraries%20almost%20always%20call%20this%20operation%20%E2%80%9Cconvolution%2C%E2%80%9D%20even%20though%20they%20compute%20the%20**cross%20correlation**%20shown%20above%3A%20they%20do%20not%20flip%20the%20filter.%20This%20does%20not%20change%20how%20the%20filter%20is%20learned.%0A%0A%20%20%20%20%23%23%23%20A%20concrete%20calculation%0A%0A%20%20%20%20If%20the%20window%20is%0A%0A%20%20%20%20%24%24%0A%20%20%20%20%5Cbegin%7Bbmatrix%7D1%262%260%5C%5C2%261%263%5C%5C0%261%262%5Cend%7Bbmatrix%7D%0A%20%20%20%20%24%24%0A%0A%20%20%20%20and%20the%20vertical%20edge%20detector%20is%0A%0A%20%20%20%20%24%24%0A%20%20%20%20%5Cbegin%7Bbmatrix%7D-1%260%261%5C%5C-1%260%261%5C%5C-1%260%261%5Cend%7Bbmatrix%7D%2C%0A%20%20%20%20%24%24%0A%0A%20%20%20%20then%20the%20output%20is%20%24(-1%2B0%2B0)%2B(-2%2B0%2B3)%2B(0%2B0%2B2)%3D2%24.%20A%20high%20value%20means%20the%20window%20resembles%20the%20target%20pattern.%20The%20same%20filter%20then%20moves%20one%20position%20and%20repeats%3A%20this%20movement%20creates%20an%20**activation%20map**.%0A%0A%20%20%20%20The%20chart%20below%20shows%20each%20window%2C%20its%20dot%20product%2C%20and%20the%20resulting%20complete%20map.%20In%20a%20real%20CNN%2C%20filter%20values%20are%20not%20set%20by%20hand%3A%20backpropagation%20adjusts%20them%20to%20minimize%20the%20loss.%0A%20%20%20%20%22%22%22)%0A%20%20%20%20return%0A%0A%0A%40app.cell(hide_code%3DTrue)%0Adef%20_()%3A%0A%20%20%20%20import%20numpy%20as%20np%0A%20%20%20%20import%20matplotlib.pyplot%20as%20plt%0A%20%20%20%20from%20matplotlib.patches%20import%20Rectangle%0A%0A%20%20%20%20%23%20A%20small%20image%20with%20a%20bright%20vertical%20bar%20in%20the%20center.%0A%20%20%20%20image%20%3D%20np.array(%5B%0A%20%20%20%20%20%20%20%20%5B0%2C%200%2C%201%2C%201%2C%200%2C%200%5D%2C%0A%20%20%20%20%20%20%20%20%5B0%2C%200%2C%201%2C%201%2C%200%2C%200%5D%2C%0A%20%20%20%20%20%20%20%20%5B0%2C%200%2C%201%2C%201%2C%200%2C%200%5D%2C%0A%20%20%20%20%20%20%20%20%5B0%2C%200%2C%201%2C%201%2C%200%2C%200%5D%2C%0A%20%20%20%20%20%20%20%20%5B0%2C%200%2C%201%2C%201%2C%200%2C%200%5D%2C%0A%20%20%20%20%20%20%20%20%5B0%2C%200%2C%201%2C%201%2C%200%2C%200%5D%2C%0A%20%20%20%20%5D%2C%20dtype%3Dfloat)%0A%20%20%20%20kernel%20%3D%20np.array(%5B%0A%20%20%20%20%20%20%20%20%5B-1%2C%200%2C%201%5D%2C%0A%20%20%20%20%20%20%20%20%5B-1%2C%200%2C%201%5D%2C%0A%20%20%20%20%20%20%20%20%5B-1%2C%200%2C%201%5D%2C%0A%20%20%20%20%5D%2C%20dtype%3Dfloat)%0A%0A%20%20%20%20def%20correlate_2d(source%2C%20filt%2C%20stride%3D1%2C%20padding%3D0)%3A%0A%20%20%20%20%20%20%20%20padded%20%3D%20np.pad(source%2C%20padding%2C%20mode%3D%22constant%22)%0A%20%20%20%20%20%20%20%20out_h%20%3D%20(padded.shape%5B0%5D%20-%20filt.shape%5B0%5D)%20%2F%2F%20stride%20%2B%201%0A%20%20%20%20%20%20%20%20out_w%20%3D%20(padded.shape%5B1%5D%20-%20filt.shape%5B1%5D)%20%2F%2F%20stride%20%2B%201%0A%20%20%20%20%20%20%20%20result%20%3D%20np.zeros((out_h%2C%20out_w))%0A%20%20%20%20%20%20%20%20for%20row%20in%20range(out_h)%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20for%20col%20in%20range(out_w)%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20window%20%3D%20padded%5B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20row%20*%20stride%20%3A%20row%20*%20stride%20%2B%20filt.shape%5B0%5D%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20col%20*%20stride%20%3A%20col%20*%20stride%20%2B%20filt.shape%5B1%5D%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%5D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20result%5Brow%2C%20col%5D%20%3D%20np.sum(window%20*%20filt)%0A%20%20%20%20%20%20%20%20return%20result%0A%0A%20%20%20%20activations%20%3D%20correlate_2d(image%2C%20kernel)%0A%20%20%20%20return%20Rectangle%2C%20activations%2C%20image%2C%20kernel%2C%20np%2C%20plt%0A%0A%0A%40app.cell(hide_code%3DTrue)%0Adef%20_(Rectangle%2C%20activations%2C%20image%2C%20kernel%2C%20np%2C%20plt)%3A%0A%20%20%20%20demo_paper%2C%20demo_ink%2C%20demo_blue%2C%20demo_coral%20%3D%20%22%23FAF7F0%22%2C%20%22%2317324D%22%2C%20%22%233A7CA5%22%2C%20%22%23E76F51%22%0A%20%20%20%20demo_fig%2C%20demo_axes%20%3D%20plt.subplots(1%2C%203%2C%20figsize%3D(14%2C%204.6)%2C%20facecolor%3Ddemo_paper)%0A%20%20%20%20for%20demo_axis%20in%20demo_axes%3A%0A%20%20%20%20%20%20%20%20demo_axis.set_facecolor(demo_paper)%0A%0A%20%20%20%20def%20matrix(demo_axis%2C%20values%2C%20title%2C%20cmap%2C%20vmin%3DNone%2C%20vmax%3DNone)%3A%0A%20%20%20%20%20%20%20%20demo_axis.imshow(values%2C%20cmap%3Dcmap%2C%20vmin%3Dvmin%2C%20vmax%3Dvmax)%0A%20%20%20%20%20%20%20%20for%20(row%2C%20col)%2C%20value%20in%20np.ndenumerate(values)%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20demo_axis.text(col%2C%20row%2C%20f%22%7Bvalue%3Ag%7D%22%2C%20ha%3D%22center%22%2C%20va%3D%22center%22%2C%20color%3Ddemo_ink%2C%20fontsize%3D10%2C%20weight%3D%22bold%22)%0A%20%20%20%20%20%20%20%20demo_axis.set_xticks(%5B%5D)%0A%20%20%20%20%20%20%20%20demo_axis.set_yticks(%5B%5D)%0A%20%20%20%20%20%20%20%20demo_axis.set_title(title%2C%20loc%3D%22left%22%2C%20color%3Ddemo_ink%2C%20fontsize%3D13%2C%20pad%3D12%2C%20weight%3D%22bold%22)%0A%0A%20%20%20%20matrix(demo_axes%5B0%5D%2C%20image%2C%20%221.%20Input%20image%20(6%20%C3%97%206)%22%2C%20%22Blues%22%2C%200%2C%201)%0A%20%20%20%20demo_axes%5B0%5D.add_patch(Rectangle((-0.5%2C%20-0.5)%2C%203%2C%203%2C%20fill%3DFalse%2C%20edgecolor%3Ddemo_coral%2C%20linewidth%3D3))%0A%20%20%20%20demo_axes%5B0%5D.text(0.5%2C%206.2%2C%20%22a%203%20%C3%97%203%20window%22%2C%20ha%3D%22center%22%2C%20color%3Ddemo_coral%2C%20fontsize%3D10)%0A%0A%20%20%20%20matrix(demo_axes%5B1%5D%2C%20kernel%2C%20%222.%20Learned%20filter%20(3%20%C3%97%203)%22%2C%20%22RdBu_r%22%2C%20-1%2C%201)%0A%20%20%20%20demo_axes%5B1%5D.text(1%2C%203.7%2C%20%22multiply%20elementwise%22%2C%20ha%3D%22center%22%2C%20color%3Ddemo_blue%2C%20fontsize%3D10)%0A%0A%20%20%20%20matrix(demo_axes%5B2%5D%2C%20activations%2C%20%223.%20Activation%20map%20(4%20%C3%97%204)%22%2C%20%22Oranges%22%2C%20-6%2C%206)%0A%20%20%20%20demo_axes%5B2%5D.text(1.5%2C%204.75%2C%20%22high%20value%20%3D%20detected%20edge%22%2C%20ha%3D%22center%22%2C%20color%3Ddemo_coral%2C%20fontsize%3D10)%0A%20%20%20%20demo_fig.suptitle(%22One%20shared%20filter%20scans%20the%20whole%20image%22%2C%20x%3D0.055%2C%20y%3D1.04%2C%20ha%3D%22left%22%2C%20color%3Ddemo_ink%2C%20fontsize%3D18%2C%20weight%3D%22bold%22)%0A%20%20%20%20plt.tight_layout()%0A%20%20%20%20demo_fig%0A%20%20%20%20return%0A%0A%0A%40app.cell(hide_code%3DTrue)%0Adef%20_(mo)%3A%0A%20%20%20%20mo.md(r%22%22%22%0A%20%20%20%20%23%23%20Output%20size%3A%20stride%2C%20padding%2C%20and%20filter%20count%0A%0A%20%20%20%20Three%20settings%20control%20the%20output%20geometry%3A%0A%0A%20%20%20%20%7C%20Setting%20%7C%20Role%20%7C%20Effect%20%7C%0A%20%20%20%20%7C---%7C---%7C---%7C%0A%20%20%20%20%7C%20Kernel%20size%20%24K%24%20%7C%20window%20size%20%7C%20a%20larger%20kernel%20sees%20more%20context%20%7C%0A%20%20%20%20%7C%20Stride%20%24S%24%20%7C%20movement%20step%20%7C%20a%20stride%20of%202%20roughly%20halves%20width%20and%20height%20%7C%0A%20%20%20%20%7C%20Padding%20%24P%24%20%7C%20border%20of%20zeros%20%7C%20preserves%20edge%20information%20and%20can%20preserve%20size%20%7C%0A%0A%20%20%20%20For%20an%20input%20of%20width%20%24W%24%2C%20the%20output%20width%20is%3A%0A%0A%20%20%20%20%24%24%0A%20%20%20%20%5Cboxed%7BW_%7Bout%7D%3D%5Cleft%5Clfloor%5Cfrac%7BW-K%2B2P%7D%7BS%7D%5Cright%5Crfloor%2B1.%7D%0A%20%20%20%20%24%24%0A%0A%20%20%20%20For%20example%2C%20%24W%3D32%24%2C%20%24K%3D3%24%2C%20%24P%3D1%24%2C%20and%20%24S%3D1%24%20gives%20%2432%24%3B%20with%20%24S%3D2%24%2C%20the%20result%20is%20%2416%24.%0A%0A%20%20%20%20A%20layer%20usually%20uses%20several%20filters.%20If%20the%20input%20has%20%24C_%7Bin%7D%24%20channels%20and%20the%20layer%20learns%20%24C_%7Bout%7D%24%20filters%2C%20each%20filter%20spans%20all%20%24C_%7Bin%7D%24%20channels%20and%20has%20shape%20%24K_h%5Ctimes%20K_w%5Ctimes%20C_%7Bin%7D%24.%20The%20output%20then%20has%20%24C_%7Bout%7D%24%20maps.%20For%20an%20RGB%20image%2C%20a%20%243%5Ctimes3%24%20filter%20has%20%243%5Ctimes3%5Ctimes3%3D27%24%20weights%20(plus%20a%20bias)%2C%20regardless%20of%20where%20it%20is%20applied.%0A%20%20%20%20%22%22%22)%0A%20%20%20%20return%0A%0A%0A%40app.cell(hide_code%3DTrue)%0Adef%20_(np%2C%20plt)%3A%0A%20%20%20%20geometry_paper%2C%20geometry_ink%2C%20geometry_blue%2C%20geometry_gold%2C%20geometry_grid%20%3D%20%22%23FAF7F0%22%2C%20%22%2317324D%22%2C%20%22%233A7CA5%22%2C%20%22%23E9C46A%22%2C%20%22%23DCE3E8%22%0A%20%20%20%20widths%20%3D%20np.arange(8%2C%2065)%0A%20%20%20%20valid%20%3D%20widths%20-%203%20%2B%201%0A%20%20%20%20same%20%3D%20widths%0A%20%20%20%20stride_two%20%3D%20np.floor((widths%20-%203%20%2B%202)%20%2F%202).astype(int)%20%2B%201%0A%0A%20%20%20%20geometry_fig%2C%20geometry_axes%20%3D%20plt.subplots(1%2C%202%2C%20figsize%3D(14%2C%204.5)%2C%20facecolor%3Dgeometry_paper)%0A%20%20%20%20for%20geometry_axis%20in%20geometry_axes%3A%0A%20%20%20%20%20%20%20%20geometry_axis.set_facecolor(geometry_paper)%0A%0A%20%20%20%20geometry_left_axis%20%3D%20geometry_axes%5B0%5D%0A%20%20%20%20geometry_left_axis.plot(widths%2C%20valid%2C%20label%3D%22K%3D3%2C%20P%3D0%2C%20S%3D1%20(valid)%22%2C%20color%3Dgeometry_blue%2C%20linewidth%3D2.5)%0A%20%20%20%20geometry_left_axis.plot(widths%2C%20same%2C%20label%3D%22K%3D3%2C%20P%3D1%2C%20S%3D1%20(same)%22%2C%20color%3Dgeometry_gold%2C%20linewidth%3D2.5)%0A%20%20%20%20geometry_left_axis.plot(widths%2C%20stride_two%2C%20label%3D%22K%3D3%2C%20P%3D1%2C%20S%3D2%22%2C%20color%3D%22%23E76F51%22%2C%20linewidth%3D2.5)%0A%20%20%20%20geometry_left_axis.scatter(%5B32%2C%2032%5D%2C%20%5B32%2C%2016%5D%2C%20color%3D%5Bgeometry_gold%2C%20%22%23E76F51%22%5D%2C%20zorder%3D3)%0A%20%20%20%20geometry_left_axis.annotate(%2232%20%E2%86%92%2032%22%2C%20(32%2C%2032)%2C%20xytext%3D(35%2C%2038)%2C%20color%3Dgeometry_ink%2C%20fontsize%3D10)%0A%20%20%20%20geometry_left_axis.annotate(%2232%20%E2%86%92%2016%22%2C%20(32%2C%2016)%2C%20xytext%3D(35%2C%2011)%2C%20color%3Dgeometry_ink%2C%20fontsize%3D10)%0A%20%20%20%20geometry_left_axis.set(xlabel%3D%22input%20width%22%2C%20ylabel%3D%22output%20width%22%2C%20xlim%3D(8%2C%2064)%2C%20ylim%3D(0%2C%2066))%0A%20%20%20%20geometry_left_axis.grid(color%3Dgeometry_grid)%0A%20%20%20%20geometry_left_axis.spines%5B%5B%22top%22%2C%20%22right%22%5D%5D.set_visible(False)%0A%20%20%20%20geometry_left_axis.legend(frameon%3DFalse%2C%20fontsize%3D9%2C%20loc%3D%22upper%20left%22)%0A%20%20%20%20geometry_left_axis.set_title(%22Geometry%3A%20stride%20shrinks%20the%20map%22%2C%20loc%3D%22left%22%2C%20color%3Dgeometry_ink%2C%20fontsize%3D13%2C%20pad%3D12%2C%20weight%3D%22bold%22)%0A%0A%20%20%20%20geometry_right_axis%20%3D%20geometry_axes%5B1%5D%0A%20%20%20%20levels%20%3D%20%5B(3%2C%201)%2C%20(3%2C%202)%2C%20(3%2C%201)%5D%20%20%23%20(kernel%2C%20stride)%0A%20%20%20%20receptive%2C%20jump%20%3D%201%2C%201%0A%20%20%20%20receptive_history%20%3D%20%5Breceptive%5D%0A%20%20%20%20for%20size%2C%20step%20in%20levels%3A%0A%20%20%20%20%20%20%20%20receptive%20%2B%3D%20(size%20-%201)%20*%20jump%0A%20%20%20%20%20%20%20%20jump%20*%3D%20step%0A%20%20%20%20%20%20%20%20receptive_history.append(receptive)%0A%20%20%20%20geometry_right_axis.bar(%5B%22input%5Cnpixels%22%2C%20%22conv%203%C3%973%22%2C%20%22conv%203%C3%973%5Cnstride%202%22%2C%20%22conv%203%C3%973%22%5D%2C%20receptive_history%2C%20color%3D%5B%22%23B9D5E5%22%2C%20geometry_blue%2C%20geometry_gold%2C%20%22%23E76F51%22%5D)%0A%20%20%20%20for%20index%2C%20value%20in%20enumerate(receptive_history)%3A%0A%20%20%20%20%20%20%20%20geometry_right_axis.text(index%2C%20value%20%2B%200.25%2C%20f%22%7Bvalue%7D%20%C3%97%20%7Bvalue%7D%22%2C%20ha%3D%22center%22%2C%20color%3Dgeometry_ink%2C%20weight%3D%22bold%22)%0A%20%20%20%20geometry_right_axis.set(ylim%3D(0%2C%2010.5)%2C%20ylabel%3D%22receptive%20field%20width%22)%0A%20%20%20%20geometry_right_axis.spines%5B%5B%22top%22%2C%20%22right%22%5D%5D.set_visible(False)%0A%20%20%20%20geometry_right_axis.grid(axis%3D%22y%22%2C%20color%3Dgeometry_grid)%0A%20%20%20%20geometry_right_axis.set_axisbelow(True)%0A%20%20%20%20geometry_right_axis.set_title(%22Depth%3A%20each%20neuron%20sees%20more%22%2C%20loc%3D%22left%22%2C%20color%3Dgeometry_ink%2C%20fontsize%3D13%2C%20pad%3D12%2C%20weight%3D%22bold%22)%0A%20%20%20%20geometry_right_axis.text(1.5%2C%209.8%2C%20%223%20%E2%86%92%205%20%E2%86%92%209%3A%20from%20local%20cues%20to%20context%22%2C%20ha%3D%22center%22%2C%20color%3Dgeometry_ink%2C%20fontsize%3D10)%0A%0A%20%20%20%20geometry_fig.suptitle(%22Architecture%20choices%20shape%20what%20a%20CNN%20can%20see%22%2C%20x%3D0.055%2C%20y%3D1.04%2C%20ha%3D%22left%22%2C%20color%3Dgeometry_ink%2C%20fontsize%3D18%2C%20weight%3D%22bold%22)%0A%20%20%20%20plt.tight_layout()%0A%20%20%20%20geometry_fig%0A%20%20%20%20return%0A%0A%0A%40app.cell(hide_code%3DTrue)%0Adef%20_(mo)%3A%0A%20%20%20%20mo.md(r%22%22%22%0A%20%20%20%20%23%23%20What%20convolution%20provides%20and%20its%20limits%0A%0A%20%20%20%20One%20convolution%20produces%20a%20score%20map%20for%20**one**%20local%20pattern.%20Multiple%20filters%20produce%20multiple%20maps%3B%20activations%20and%20later%20layers%20determine%20how%20to%20combine%20them.%20A%20%5BCNN%5D(%2Fmodels%2Fcnn)%20organizes%20these%20building%20blocks%20into%20a%20complete%20architecture.%0A%0A%20%20%20%20Weight%20sharing%20gives%20**translation%20equivariance**%3A%20moving%20a%20pattern%20moves%20its%20response.%20Approximate%20invariance%20(recognizing%20a%20pattern%20despite%20a%20small%20shift)%20comes%20more%20from%20aggregation%20and%20training%20data.%20Convolution%20alone%20is%20not%20automatically%20robust%20to%20rotation%2C%20lighting%2C%20or%20changes%20in%20scale.%0A%0A%20%20%20%20%23%23%20Common%20pitfalls%0A%0A%20%20%20%20-%20A%20high%20value%20in%20a%20map%20is%20not%20a%20probability%3A%20it%20is%20a%20similarity%20score%20before%20later%20operations.%0A%20%20%20%20-%20Padding%20usually%20adds%20zeros%2C%20so%20image%20borders%20do%20not%20have%20exactly%20the%20same%20context%20as%20the%20center.%0A%20%20%20%20-%20Rotation%2C%20scale%2C%20and%20lighting%20changes%20must%20be%20addressed%20through%20data%2C%20augmentation%2C%20or%20the%20full%20architecture.%0A%0A%20%20%20%20%23%23%20Key%20takeaway%0A%0A%20%20%20%20When%20examining%20a%20convolutional%20layer%2C%20ask%20four%20questions%3A%20**What%20is%20the%20window%20size%3F%20How%20many%20filters%3F%20What%20stride%20and%20padding%3F%20What%20output%20size%3F**%20The%20answers%20explain%20the%20computation%2C%20parameter%20count%2C%20and%20portion%20of%20the%20image%20the%20network%20can%20use.%0A%0A%20%20%20%20%23%23%20Before%20and%20after%0A%0A%20%20%20%20-%20Before%3A%20%5BThe%20Perceptron%5D(%2Fconcepts%2Fperceptron)%20introduces%20weighted%20computation%3B%20%5BBackpropagation%5D(%2Fconcepts%2Fbackpropagation)%20explains%20how%20filters%20are%20learned.%0A%20%20%20%20-%20After%3A%20%5BCNNs%5D(%2Fmodels%2Fcnn)%20shows%20how%20convolutions%20are%20combined%20to%20solve%20a%20vision%20task.%0A%20%20%20%20%22%22%22)%0A%20%20%20%20return%0A%0A%0Aif%20__name__%20%3D%3D%20%22__main__%22%3A%0A%20%20%20%20app.run()%0A
aff7907919350ee1d11e38a2ddca0632