From 82ee2c83431584beca560cba5b52e62c99020bf0 Mon Sep 17 00:00:00 2001 From: Pavan Srinivas Date: Thu, 8 Jan 2026 11:02:05 +0000 Subject: [PATCH] Added sample code for quadratic cost for single neuron. --- digit_prediction.png | Bin 0 -> 6927 bytes guess_test.py | 35 ++++++++++++++ network.py | 11 ++++- practice.py | 0 quadratic_cost_demo.py | 102 ++++++++++++++++++++++++++++++++++++++++ quadratic_cost_plot.png | Bin 0 -> 47471 bytes test.py | 25 +++++----- 7 files changed, 161 insertions(+), 12 deletions(-) create mode 100644 digit_prediction.png create mode 100644 guess_test.py create mode 100644 practice.py create mode 100644 quadratic_cost_demo.py create mode 100644 quadratic_cost_plot.png diff --git a/digit_prediction.png b/digit_prediction.png new file mode 100644 index 0000000000000000000000000000000000000000..f086839a2ac4a18ad1225ae35fdc15ccc91407ae GIT binary patch literal 6927 zcmeHMX;f2L)(zTKR22mnDV1VWY(+{T1!!cZEDQkB2yp?!J&j8lLN>Q z1`7=lK}I3S5VV+7WK4iCD-pt!1PBnu(D(VR)&2eGRcm#1)4%%1TdenZ@7{CI*=O%_ zPGWwsG?V;B?i&~kCVA$xi46?4%^teG`Vu^$d!!D6KYD?u>;r9a9)ZD^{n0Rs%YoN? zaDhG;x4n3@e*gxD)z;AbQA6j*Ua!EwYXN!)gzw+q(7^e7B3?TLwSiT>zIOUz01PI5 z8M?%t8dEVam|WNylN0AcGPpxwKHZBeujV)f>a5?aJ91>oZ(AyQkoU}5!h_O$p2AIP zj#!(1_dbw^%F*=iV;*pbi)l$pCA1W1H9mVfP-=0?>8@IUGwUbS-JK=qy>d4uVJqvR zy$iHUKYe565M5;VyRzX%7H3VDvtz!ElOdqkpwz@*Kc!nOE^LFr@W^cvu)S%ow!uyx zEQZ1Ee|-dY{mQ@c=%!UAin5cDYcV~E4ljt4)l@N!lkHp*+&^HRW0TjwrHu@`d#@Ht z7r~c9;P!VXn&feD-~%(|hy{GReTC1(vt*=tR-|a9=62A%Id-!d#inmGyKZxXpP8lW z*_MIVzIyelTgRglexemlvv*N#&lia~)9*9&kLOyDck^ommR1N#<^ZlPBEQHXARxdB z0T*%33m3MzdUg#CDo9F7&b`-eZ^$pA%VlrOc1lSYa5y$SJ>7B$#~XYJtuJd#44)}!R&pw<hYKs+%7hoo zJS-L_8J^K?)w;>31Nc64%EC)SG;pP+SH~kf4OkpD7mo|yZ>cx=gyoqX5$c657R>J6 z_g4%sfF7~d^wjz>w1q=Bc`P${IEEk2(eLc&*ijoMOxRc&K(rZeuG^QmoqC_9t(ssk z|Axep-9;WQ?OW)}j*5zc&L5qoEHY^8FZXtTm!zh7<;`7IgmCDwRkl$lllfhuv1l1- z`0!Nh?#3>Px&Gqv@t4zu)evY1oJ^XNaOD02OFcCeWR#Cd!wU=p`iINrYOfB6c@A!b zuIa-nu3&?kHd(DJrJ|C|WcO!nr^~C-0@o`ygkFyI?-G|!@g@cuox#ZD4&um|b zToS1}-_Fd|*7k^F<&Ou?rtUCP@G~i}FH!Mm&r-zES3JH|GSDH;-coKzQnPg%ZHR#! z0*5y%20K!F<^iml+9O2*9pPXAJ117-&iVWcjq0?)ozx6}l!4&Aw(?33`@`#7>|bRp zNxA{!fm1cpJKMi?w?@T~ zNZy4n4;EHUJ(E3-b#w%HED2wkU!Jszl&g=HPBh+JY4^qT4*9oy2BZ$Jl07;wBEr`! z^?UoRPEyT)tKBv?gd@Y-PkxQWHhFN^P6@$nGA&ryw8|i+eWs&u852jt?z`7 z1=p=PsZo+7<&jAMbVcFQ4kK5C2Z7sACP@z;K9tf%`mlaMsf_{0tHZ6a)!YiHW@c}1 ziiAexqk67t#V@Q%ot^hOowW z5rjCIbO<2GoyxC%%T6?QR>>I*oqmp9nIA&~<`}zYrlbZ)g<_MJ1X89V$>tq1&(_=| zDWKhuHnfp)vd%CmQtKU^Um4X(T3=FZhu!@*A7rmTF)_jT`f}%wJuIE$zg}7|6ZJUYlAUWq zll|CDL96svYM z7#bM;Js<&J!}I6Qcjns_kw~oK%O?vQUuyLfxhS8EmWtoBG;wc0 zyMvW}nRI@%Me2|HrlzLcMk0jq){jja(~o(7=9%A4Mpx+bMq?3JVSu^0IY`KTP+}dv zP~f#z)^4=ca6?>)wS=5pUlFiD>e@L1toXKr)p4dg`Wnx{X<&Y=h5c4FJML?lgAHQh z3LU)Qfq6ZAw;bnvTA5R|U71JgopSHq(6Ajl!D;awAXj%lr<1WVDB%iDz~Mkf0v&^g zg61Y3CpM+jt&fpd%gEj|&#XT6=_+=D{%F;7VJyTjRYBAJSY@4St|=L~#i{PO54WV7 z)TkL(6a6Ce0cCptb zku-5_Ft_DrpVr)#Q{f^(_DF@eVBb(lQyawG#EsQPJNkU`i?rD@s>QD2hD$8>xx~oz z{T^)@-vi@kX4e33RJ`i9cIa1J0e0koeYqTcevNihqO!7QhM(!#ECbzDAzvB9YVNV} z##3(D**>L^4>yu<(%AXii16R)59~!!D=I36+U1cxBp|1CqQ#;CLsjw&IIr6D09=`R zOv9<_XjbS{9+Z_-#7Qxqv{yG3nLrXZ)`W?W6e<#XySjD?Mh1lwq(pP~ z5&Pn9fE**Zk+vC&jz{3oi*4H>e3c20l3mQT9N>Tb_&;CiE%aj#AbB#?TfcVT%Uj8dH-l( zt7fx;4B$M-Yk)QIP=GyJ(|37h23?DKQ4A^d%vKj3R zR&k72?DlKiW!C`8xY0Q6HqsD&K>d<~16#DlPmGaKZ4v@EKF!OE0dZXjp{v-;7Ai8BcL>OpL z-cf@2!(+?rM1+9T&cBux1xXCZ{|ZPwhHJx8>ZOfq4Ay7s$8Jh!99mpl6=z-V5o%TARFc?|#26LDTbQpyhY~#?O^#lUkB3DTt97J|Cc53s7Sh z)hZjh=3ll)6gv99Juo(w;(`qxj6XhX|D}|IeW;M<6eXp2DJy*btyDW_T!R5rO=9F8sBTVP1Y|{Ry+Z=3Y)M`OrJuI%1rw+fOxKhC@ZgQqmcceZ z$p%Hscxp45!03nv1#dZ%07}L@fsxvU=a-W8_=w0A^C<&X`tgx)?Vw>$8?c!Kz(H1- zX6@6tGbOh`Dp~xeQ|bSFG!425RHhKLqMAX&fU+1KlAsZR+yY4Y9@4vk1jm%As3ho) zr@pv|tC=(HFCdYC-WmrDH}?U;V|b{$&<&vXJ&gouOhVd24X1QHoM?R|Pq6%{7_xk8 zNZ<588o0wg0d&SZj;zw0954wWaZ~0 zE>8C%pqm3Jj`#KWxnwMAOC9}>;KOG3d1etjrfQ(h%(v&}7ZP0_r%WCNShbKY{s!(am|38pXl#TwY)^28RCz6n<9ZMWB+D);n*U23RHT3}DV+ z@JK|SfVC26yTp3E4ff{Gje-8i2r!I+O-$T3*EmByZ)cZ+JghPb#zG(^=UWie)|-hk zTc;ugVAwU}pM#?4TW;^zp8zHfOhTgJ62J}US6^I&!}puUohC1SdSI2?degUaYl8v# z0sp1T#+02cr<=)q(i*zZX$FPBU}J%iCvf$=0wLkwn8p3`AY2$?NWdo4K(~o0GfhxP z1O9j8_Jf;T%gl7>W~eG?>vsPPCuklA3w`(L?E{8~B60a6l(0krdE`lJx_&UW|A^}V z1ie2wf&7CH{~!LZXR^RJ%Z6h(`)WI;474*3pre0!a}QGnnuipmgs3-Yt1{s8P_^5z z7Us$+2W@t4TlL2%c^eLBIw-BH-9^M?$dut4LZ09{54|-Q0236ft~I4gkt&A&1#H}3 zKoE=r9w0%(v#FZK*ge!%IbHuNfbR#(#Wst`rOl8&BDbWhgR}^yjEIkq$CQCC;65_{ zaJaB~#DZKNGB^6-;;T)gEo6i$>K@ok>gwt$lK?gMwj6XinEOrDL@N_@f|Onz#Q&)= z_#c4qAJK0LD0lh;dJ^DCxeQwCh$fAaverllmx0P!P4^h}yopVY)N_ z>FVNh(f=$gRBZMP)RG~+d!2$U$jQE-F$Gdr(EM9f zsO+5rZ=xL)YCH)47PCS-%pLw&F!A6n`{S< Tm=*Bb6zt3?OOwK%U2pyk=r1}j literal 0 HcmV?d00001 diff --git a/guess_test.py b/guess_test.py new file mode 100644 index 0000000..3829565 --- /dev/null +++ b/guess_test.py @@ -0,0 +1,35 @@ +import mnist_loader +import network +import numpy as np +import matplotlib.pyplot as plt + +# Load data +training_data, validation_data, test_data = mnist_loader.load_data_wrapper() +# Ensure test_data is a list of (x, y) pairs +test_data = list(test_data) + +# Pick one sample +x, y = test_data[0] + +# Create and train a network +net = network.Network([784, 30, 10]) +training_data = list(training_data) +net.SGD(training_data, 1, 10, 3.0) + +# Call the guess function defined in network.py (it expects self, x) +pred_by_guess = network.guess(net, x) + +# Reshape x from (784, 1) to (28, 28) and display as image +x_image = x.reshape(28, 28) +plt.figure(figsize=(6, 6)) +plt.imshow(x_image, cmap='gray') +plt.title(f"Actual: {y}, Predicted: {int(pred_by_guess)}") +plt.axis('off') +plt.tight_layout() +plt.savefig('digit_prediction.png') +plt.show() +print(f"Image saved as digit_prediction.png") + + +print("Actual label:", y) +print("network.guess predicted:", int(pred_by_guess)) diff --git a/network.py b/network.py index 78629cf..73a4232 100644 --- a/network.py +++ b/network.py @@ -84,7 +84,7 @@ def update_mini_batch(self, mini_batch, eta): for x, y in mini_batch: delta_nabla_b, delta_nabla_w = self.backprop(x, y) nabla_b = [nb+dnb for nb, dnb in zip(nabla_b, delta_nabla_b)] - nabla_w = [nw+dnw for nw, dnw in zip(nabla_w, delta_nabla_w)] + nabla_w = [nw+dnw for nw, dnw in zip(nabla_w, delta_nabla_w)] self.weights = [w-(eta/len(mini_batch))*nw for w, nw in zip(self.weights, nabla_w)] self.biases = [b-(eta/len(mini_batch))*nb @@ -95,6 +95,7 @@ def backprop(self, x, y): gradient for the cost function C_x. ``nabla_b`` and ``nabla_w`` are layer-by-layer lists of numpy arrays, similar to ``self.biases`` and ``self.weights``.""" + # print("weights first row: {}".format(self.weights[0])) nabla_b = [np.zeros(b.shape) for b in self.biases] nabla_w = [np.zeros(w.shape) for w in self.weights] # feedforward @@ -139,6 +140,14 @@ def cost_derivative(self, output_activations, y): \partial a for the output activations.""" return (output_activations-y) +def guess(self, x): + """Return the index of the highest activation neuron.""" + activation = x + + for b, w in zip(self.biases, self.weights): + activation = sigmoid(np.dot(w, activation)+b) + + return np.argmax(activation) #### Miscellaneous functions def sigmoid(z): """The sigmoid function.""" diff --git a/practice.py b/practice.py new file mode 100644 index 0000000..e69de29 diff --git a/quadratic_cost_demo.py b/quadratic_cost_demo.py new file mode 100644 index 0000000..330d31d --- /dev/null +++ b/quadratic_cost_demo.py @@ -0,0 +1,102 @@ +"""quadratic_cost_demo.py +~~~~~~~~~~~~~~~~~~~~~~~~ + +Demonstration of quadratic cost function during gradient descent training. + +""" + +import numpy as np +import matplotlib.pyplot as plt + + +def sigmoid(z): + """The sigmoid function.""" + return 1.0/(1.0+np.exp(-z)) + + +def sigmoid_prime(z): + """Derivative of the sigmoid function.""" + return sigmoid(z)*(1-sigmoid(z)) + + +def quadraticCostDemo(epochs): + """Demonstrate quadratic cost function over epochs.""" + w = 0.6 + b = 0.9 + x = 1 + y = 0 # desired output + cost_history = {} # dictionary to store cost values + + # Enable interactive mode for real-time plotting + plt.ion() + fig, ax = plt.subplots(figsize=(10, 6)) + + for i in range(1, epochs): + z = w * x + b + a = sigmoid(z) + cost = 0.5 * (a - y) ** 2 + cost_history[i] = cost + + # Calculate gradients + nabla_cW = (a - y) * sigmoid_prime(z) * x + nabla_cB = (a - y) * sigmoid_prime(z) + + # Update weights and bias + w = w - nabla_cW + b = b - nabla_cB + + # Update plot in real-time + if i % 5 == 0 or i == 1: # Update every 5 epochs for better visualization + ax.clear() + epoch_list = sorted(cost_history.keys()) + cost_list = [cost_history[e] for e in epoch_list] + + ax.plot(epoch_list, cost_list, 'b-', linewidth=2) + ax.set_xlabel('Epoch', fontsize=12) + ax.set_ylabel('Quadratic Cost', fontsize=12) + ax.set_title('Quadratic Cost Function Over Training Epochs', fontsize=14) + ax.grid(True, alpha=0.3) + plt.tight_layout() + plt.pause(0.01) # Small pause to see the update + + # Turn off interactive mode + plt.ioff() + + return cost_history + + +def plot_cost_history(cost_history): + """Plot the cost function over epochs.""" + epochs = sorted(cost_history.keys()) + costs = [cost_history[epoch] for epoch in epochs] + + plt.figure(figsize=(10, 6)) + plt.plot(epochs, costs, 'b-', linewidth=2) + plt.xlabel('Epoch', fontsize=12) + plt.ylabel('Quadratic Cost', fontsize=12) + plt.title('Quadratic Cost Function Over Training Epochs', fontsize=14) + plt.grid(True, alpha=0.3) + plt.tight_layout() + plt.savefig('quadratic_cost_plot.png', dpi=150, bbox_inches='tight') + print("Plot saved to quadratic_cost_plot.png") + plt.show() + + +if __name__ == "__main__": + # Run the demo with 100 epochs + epochs = 300 + cost_history = quadraticCostDemo(epochs) + + # Save final plot + plt.figure(figsize=(10, 6)) + epoch_list = sorted(cost_history.keys()) + cost_list = [cost_history[e] for e in epoch_list] + plt.plot(epoch_list, cost_list, 'b-', linewidth=2) + plt.xlabel('Epoch', fontsize=12) + plt.ylabel('Quadratic Cost', fontsize=12) + plt.title('Quadratic Cost Function Over Training Epochs', fontsize=14) + plt.grid(True, alpha=0.3) + plt.tight_layout() + plt.savefig('quadratic_cost_plot.png', dpi=150, bbox_inches='tight') + print("Plot saved to quadratic_cost_plot.png") + plt.show() diff --git a/quadratic_cost_plot.png b/quadratic_cost_plot.png new file mode 100644 index 0000000000000000000000000000000000000000..9ac8298c24c9b8fe1adbf00a4bb12719bd97ad88 GIT binary patch literal 47471 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 literal 0 HcmV?d00001 diff --git a/test.py b/test.py index d1f4996..f6b84df 100644 --- a/test.py +++ b/test.py @@ -17,19 +17,18 @@ # ---------------------- # - read the input data: -''' + import mnist_loader training_data, validation_data, test_data = mnist_loader.load_data_wrapper() training_data = list(training_data) -''' # --------------------- # - network.py example: -#import network +import network + -''' net = network.Network([784, 30, 10]) -net.SGD(training_data, 30, 10, 3.0, test_data=test_data) -''' +net.SGD(training_data, 1, 10, 3.0, test_data=test_data) + # ---------------------- # - network2.py example: @@ -124,6 +123,7 @@ """ +''' def testTheano(): from theano import function, config, shared, sandbox import theano.tensor as T @@ -149,17 +149,18 @@ def testTheano(): print('Used the gpu') # Perform check: #testTheano() +''' # ---------------------- # - network3.py example: -import network3 -from network3 import Network, ConvPoolLayer, FullyConnectedLayer, SoftmaxLayer # softmax plus log-likelihood cost is more common in modern image classification networks. +# import network3 +# from network3 import Network, ConvPoolLayer, FullyConnectedLayer, SoftmaxLayer # softmax plus log-likelihood cost is more common in modern image classification networks. # read data: -training_data, validation_data, test_data = network3.load_data_shared() -# mini-batch size: -mini_batch_size = 10 +# training_data, validation_data, test_data = network3.load_data_shared() +# # mini-batch size: +# mini_batch_size = 10 # chapter 6 - shallow architecture using just a single hidden layer, containing 100 hidden neurons. ''' @@ -195,6 +196,7 @@ def testTheano(): ''' # chapter 6 - rectified linear units and some l2 regularization (lmbda=0.1) => even better accuracy +''' from network3 import ReLU net = Network([ ConvPoolLayer(image_shape=(mini_batch_size, 1, 28, 28), @@ -208,3 +210,4 @@ def testTheano(): FullyConnectedLayer(n_in=40*4*4, n_out=100, activation_fn=ReLU), SoftmaxLayer(n_in=100, n_out=10)], mini_batch_size) net.SGD(training_data, 60, mini_batch_size, 0.03, validation_data, test_data, lmbda=0.1) +''' \ No newline at end of file