From a82b17fabe48ae7c2ad32da6eccef68c8385cd28 Mon Sep 17 00:00:00 2001 From: judsonupchurch Date: Mon, 27 Jan 2025 19:39:18 +0000 Subject: [PATCH] Lecture 30. L1 and L2 Regularization --- lecture28_31/notes_28.ipynb | 270 +++++++++++++++++++++++++++++++++++- lecture28_31/notes_28.pdf | Bin 73679 -> 90753 bytes lecture28_31/notes_28.py | 237 +++++++++++++++++++++++++++++++ 3 files changed, 505 insertions(+), 2 deletions(-) diff --git a/lecture28_31/notes_28.ipynb b/lecture28_31/notes_28.ipynb index c07907b..5dbab4c 100644 --- a/lecture28_31/notes_28.ipynb +++ b/lecture28_31/notes_28.ipynb @@ -9,7 +9,7 @@ }, { "cell_type": "code", - "execution_count": 1, + "execution_count": 3, "metadata": {}, "outputs": [], "source": [ @@ -23,7 +23,7 @@ }, { "cell_type": "code", - "execution_count": 2, + "execution_count": 4, "metadata": {}, "outputs": [], "source": [ @@ -464,6 +464,272 @@ "## Data Leakage\n", "While K-Fold is good for getting hyper-parameters with limited data, it can have data leakage if not correctly setup. For example, with timeseries data, it may get access to future information and train off of that." ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# L1/L2 Regularization\n", + "## How it Works\n", + "When a network is overfitting the data, it typically has larger weights and biases. By punishing the neural network for larger weights and biases, we can try to reduce the chances of overfitting.\n", + "\n", + "We add the L1 or L2 loss to the data loss. L1 is the summation of the absolute value of all the weights. L2 is the summation of the weights squared. L2 is typically preferred due to the smoother gradient and still allowing small weights and biases.\n", + "\n", + "## Backward Pass\n", + "### L1\n", + "$\\frac{\\delta L}{\\delta w} = \\lambda \\text{ if } w \\gt 0, \\text{ else } -\\lambda$\n", + "\n", + "### L2\n", + "$\\frac{\\delta L}{\\delta w} = 2\\lambda w$" + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "metadata": {}, + "outputs": [], + "source": [ + "import numpy as np\n", + "\n", + "class Layer_Dense:\n", + " def __init__(self, n_inputs, n_neurons,\n", + " weight_regularizer_l1=0, weight_regularizer_l2=0,\n", + " bias_regularizer_l1=0, bias_regularizer_l2=0):\n", + " # Initialize the weights and biases\n", + " self.weights = 0.01 * np.random.randn(n_inputs, n_neurons)\n", + " self.biases = np.zeros((1, n_neurons))\n", + " # Set the regularization strength\n", + " self.weight_regularizer_l1 = weight_regularizer_l1\n", + " self.weight_regularizer_l2 = weight_regularizer_l2\n", + " self.bias_regularizer_l1 = bias_regularizer_l1\n", + " self.bias_regularizer_l2 = bias_regularizer_l2\n", + "\n", + " def forward(self, inputs):\n", + " # Calculate the output values from inputs, weights, and biases\n", + " self.inputs = inputs\n", + " self.output = np.dot(inputs, self.weights) + self.biases # Weights are already transposed\n", + " \n", + " def backward(self, dvalues):\n", + " '''Calculated the gradient of the loss with respect to the weights and biases of this layer.\n", + " dvalues is equiavelent to a transposed dl_dZ. It is the gradient \n", + " of the loss with respect to the outputs of this layer.'''\n", + " # Gradients based on parameters\n", + " self.dweights = np.dot(self.inputs.T, dvalues)\n", + " self.dbiases = np.sum(dvalues, axis=0, keepdims=True)\n", + " self.dinputs = np.dot(dvalues, self.weights.T)\n", + "\n", + " # Now we look at the gradients on regularization\n", + " # L1\n", + " if self.weight_regularizer_l1 > 0:\n", + " dL1 = np.ones_like(self.weights)\n", + " dL1[self.weights < 0] = -1\n", + " self.dweights += self.weight_regularizer_l1 * dL1\n", + " if self.bias_regularizer_l1 > 0:\n", + " dL1 = np.ones_like(self.biases)\n", + " dL1[self.biases < 0] = -1\n", + " self.dbiases += self.bias_regularizer_l1 * dL1\n", + "\n", + " # L2\n", + " if self.weight_regularizer_l2 > 0:\n", + " self.dweights += 2 * self.weight_regularizer_l2 * self.weights\n", + " if self.bias_regularizer_l2 > 0:\n", + " self.dbiases += 2 * self.bias_regularizer_l2 * self.biases\n", + "\n", + "# Base class for Loss functions\n", + "class Loss:\n", + " '''Calculates the data and regularization losses given\n", + " model output and ground truth values'''\n", + " def regularization_loss(self, layer):\n", + " regularization_loss = 0\n", + "\n", + " # L1 regularization\n", + " if layer.weight_regularizer_l1 > 0:\n", + " regularization_loss += layer.weight_regularizer_l1 * np.sum(np.abs(layer.weights))\n", + " if layer.bias_regularizer_l1 > 0:\n", + " regularization_loss += layer.bias_regularizer_l1 * np.sum(np.abs(layer.biases))\n", + "\n", + " # L2 regularization\n", + " if layer.weight_regularizer_l2 > 0:\n", + " regularization_loss += layer.weight_regularizer_l1 * np.sum(layer.weights * layer.weights)\n", + " if layer.bias_regularizer_l2 > 0:\n", + " regularization_loss += layer.bias_regularizer_l1 * np.sum(layer.biases * layer.biases)\n", + "\n", + " return regularization_loss\n", + "\n", + " def calculate(self, output, y):\n", + " sample_losses = self.forward(output, y)\n", + " data_loss = np.average(sample_losses)\n", + " return data_loss\n", + "\n", + "class Loss_CategoricalCrossEntropy(Loss):\n", + " def forward(self, y_pred, y_true):\n", + " '''y_pred is the neural network output\n", + " y_true is the ideal output of the neural network'''\n", + " samples = len(y_pred)\n", + " # Bound the predicted values \n", + " y_pred_clipped = np.clip(y_pred, 1e-7, 1-1e-7)\n", + " \n", + " if len(y_true.shape) == 1: # Categorically labeled\n", + " correct_confidences = y_pred_clipped[range(samples), y_true]\n", + " elif len(y_true.shape) == 2: # One hot encoded\n", + " correct_confidences = np.sum(y_pred_clipped*y_true, axis=1)\n", + "\n", + " # Calculate the losses\n", + " negative_log_likelihoods = -np.log(correct_confidences)\n", + " return negative_log_likelihoods\n", + " \n", + " def backward(self, dvalues, y_true):\n", + " samples = len(dvalues)\n", + "\n", + " # Number of lables in each sample\n", + " labels = len(dvalues[0])\n", + "\n", + " # if the labels are sparse, turn them into a one-hot vector\n", + " if len(y_true.shape) == 1:\n", + " y_true = np.eye(labels)[y_true]\n", + "\n", + " # Calculate the gradient then normalize\n", + " self.dinputs = -y_true / dvalues\n", + " self.dinputs = self.dinputs / samples\n", + "\n", + "class Activation_Softmax_Loss_CategoricalCrossentropy():\n", + " def __init__(self):\n", + " self.activation = Activation_Softmax()\n", + " self.loss = Loss_CategoricalCrossEntropy()\n", + "\n", + " def forward(self, inputs, y_true):\n", + " self.activation.forward(inputs)\n", + " self.output = self.activation.output\n", + " return self.loss.calculate(self.output, y_true)\n", + " \n", + " def backward(self, dvalues, y_true):\n", + " samples = len(dvalues)\n", + "\n", + " # if the samples are one-hot encoded, turn them into discrete values\n", + " if len(y_true.shape) == 2:\n", + " y_true = np.argmax(y_true, axis=1)\n", + " \n", + " # Copy so we can safely modify\n", + " self.dinputs = dvalues.copy()\n", + " \n", + " # Calculate and normalize gradient \n", + " self.dinputs[range(samples), y_true] -= 1\n", + " self.dinputs = self.dinputs / samples" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Testing Regularization" + ] + }, + { + "cell_type": "code", + "execution_count": 16, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "epoch: 10000, acc: 0.913, loss: 0.210, lr: 0.019980019980019983\n", + "validation, acc: 0.820, loss: 0.694\n" + ] + } + ], + "source": [ + "# Create dataset\n", + "X, y = spiral_data(samples=100, classes=3)\n", + "\n", + "# Create Dense layer with 2 input features and 64 output values\n", + "dense1 = Layer_Dense(2, 64, weight_regularizer_l2=5e-4, bias_regularizer_l2=5e-4)\n", + "\n", + "# Create ReLU activation (to be used with Dense layer)\n", + "activation1 = Activation_ReLU()\n", + "\n", + "# Create second Dense layer with 64 input features (as we take output\n", + "# of previous layer here) and 3 output values (output values)\n", + "dense2 = Layer_Dense(64, 3)\n", + "\n", + "# Create Softmax classifier's combined loss and activation\n", + "loss_activation = Activation_Softmax_Loss_CategoricalCrossentropy()\n", + "\n", + "# Create optimizer\n", + "optimizer = Optimizer_Adam(learning_rate=0.02, decay=1e-7)\n", + "\n", + "# Train in loop\n", + "for epoch in range(10001):\n", + " # Perform a forward pass of our training data through this layer\n", + " dense1.forward(X)\n", + " \n", + " # Perform a forward pass through activation function\n", + " # takes the output of first dense layer here\n", + " activation1.forward(dense1.output)\n", + " \n", + " # Perform a forward pass through second Dense layer\n", + " # takes outputs of activation function of first layer as inputs\n", + " dense2.forward(activation1.output)\n", + " \n", + " # Perform a forward pass through the activation/loss function\n", + " # takes the output of second dense layer here and returns loss\n", + " data_loss = loss_activation.forward(dense2.output, y)\n", + "\n", + " regularization_loss = (\n", + " loss_activation.loss.regularization_loss(dense1) +\n", + " loss_activation.loss.regularization_loss(dense2)\n", + " )\n", + "\n", + " loss = data_loss + regularization_loss\n", + " \n", + " # Calculate accuracy from output of activation2 and targets\n", + " # calculate values along first axis\n", + " predictions = np.argmax(loss_activation.output, axis=1)\n", + " if len(y.shape) == 2:\n", + " y = np.argmax(y, axis=1)\n", + " accuracy = np.mean(predictions == y)\n", + " \n", + " # Backward pass\n", + " loss_activation.backward(loss_activation.output, y)\n", + " dense2.backward(loss_activation.dinputs)\n", + " activation1.backward(dense2.dinputs)\n", + " dense1.backward(activation1.dinputs)\n", + " \n", + " # Update weights and biases\n", + " optimizer.pre_update_params()\n", + " optimizer.update_params(dense1)\n", + " optimizer.update_params(dense2)\n", + " optimizer.post_update_params()\n", + "\n", + "# After Training\n", + "print(f'epoch: {epoch}, ' +\n", + " f'acc: {accuracy:.3f}, ' +\n", + " f'loss: {loss:.3f}, ' +\n", + " f'lr: {optimizer.current_learning_rate}')\n", + "\n", + "\n", + "# With the weights and biases now optimized based on the training data, lets validate it\n", + "# Create test dataset\n", + "X_test, y_test = spiral_data(samples=100, classes=3)\n", + "# Perform a forward pass of our testing data through this layer\n", + "dense1.forward(X_test)\n", + "# Perform a forward pass through activation function\n", + "# takes the output of first dense layer here\n", + "activation1.forward(dense1.output)\n", + "# Perform a forward pass through second Dense layer\n", + "# takes outputs of activation function of first layer as inputs\n", + "dense2.forward(activation1.output)\n", + "# Perform a forward pass through the activation/loss function\n", + "# takes the output of second dense layer here and returns loss\n", + "loss = loss_activation.forward(dense2.output, y_test)\n", + "# Calculate accuracy from output of activation2 and targets\n", + "# calculate values along first axis\n", + "predictions = np.argmax(loss_activation.output, axis=1)\n", + "if len(y_test.shape) == 2:\n", + " y_test = np.argmax(y_test, axis=1)\n", + "accuracy = np.mean(predictions == y_test)\n", + "print(f'validation, acc: {accuracy:.3f}, loss: {loss:.3f}')" + ] } ], "metadata": { diff --git a/lecture28_31/notes_28.pdf b/lecture28_31/notes_28.pdf index 3703e56e72f5c46ec8a9195ea272333f10feb158..c760db3814b38fabaa01e50af09372b1d5fc688e 100644 GIT binary patch delta 52470 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 ?76wk^3 z4rMUDy|dxvfHz_@Y(=I5BBhU|vkn)j0qH zHReY@5t6v>AqQg=Uy1B+J6ydsg@ZeD9@F^NTg`Yf^9l8d1#vho(oTFVoA5fX ztR!z~>#U6e){0JEk-K*Mfant-tas#Yw=C$% zf4{H%)&&+}s&NS0x3dsH{ae`*#-rpX70vUCWGB%96sI4>>ODNO(8O^|JtM_+eQWK5 z%5c^LeHsqIb-*jY#*@3~_C!}P7Emw>L7@=M z60TSFS0{om1w;BVST!tqEJL{X?2(UO*RK}};z3}IR8Qz=*7p&L0q-d<2f8U`t96=I zQo^bL9l2u$^S&sZzsD$#0qfwUWK$8r4MrY5__8A?NKalNNz~1|mIY(1zyjFh8$ehS zB!Yb;TSJ9)Tp4{7UxI$wF#aUj4MVKHWme-Q@0BjjS5H4%gLLrW2f41FP-={|p}A-sI_73q;IbUR+lP z^TxHOxq>F09Y8o86r|_$U{IgxCvbVytBxFEp=%dzGYR_6OB5MxvqM(&kW_aABsve5 zKAalTN}Vi*5cIGe>%KPZ$waoj4B6ZI;Mt~8V>_6#I37;7+DD8|&WNfb?OliMA+J!) zK(G&l4IFX$oQqWBT~a?@&#|es5EpuJKQPKOv>N;A1RObN(0sjC<<_d!%7=_0^lAM= zOs}@bB*oXEh&W8jZUPJLkWu*I4h1%06t%>1chKoIAHltrCpbGb*VYzkP*^IfjgX2K zy)wL5acT6fgu3^6|FTZX0VvY>;dJ?Q9eH!x;G49O-K1@0Dk29QxVWfQbB7OMe}pp9 zg^w%B2+Oc=Bcd9OWyi$gYq3?b(oNu%Y6s$mW%CSb2n7QBBCYML$o!b_e{GO?yekco ztvAD94`_i@vWn`in0h<|vxMwLdhj?F{x$ZAaJT!XHmIR!dfVr!UEGkuHMOmWqE&2& z1(b}O`!^yERGnHn5h;;r*b=9OSd96)4k9YhG4{P%JSwr0=jmXWuatANWtZ*LiJLEc zT*e%QxoylOB|RxYDSf>cAO(F#4dYgr_3=4|f7*3U@Z2zgJMz@n+^VLczonv(-?X8* zkXEOyHLtNXyqCP9)44PFp%M#Y66xcGb_XU*lrG)#prQWI)17hKI+s zw7o5hNh$FUXH*mM0mAH$x33Jz;&<}Oo#x{dhFR^kVuCPc0fZto4))`ENC3T7& zUQgfF&Z@7i6~4oMftZ4>nzSGlh4gl!srWz|M`?@UPATc#1;j3QDL{vRH z+DA&%9yRI|O@HnA!yV(mUlsmGVh&Px%z-ihIW|k$%J(nQW3HAJagU$Z3KJ+7QxYb{ zu{ZGr+_9ouh+e(y;0|2X+FC?}23xu%o^%tv@5r_5+~B?y&x~5a|VT zF-9{-UtQ+#{jDq!FTP7;X4&u)uiOK^n&YKh?c-O#*9UkMV6XwAqZvp=8!m%O#aPh5 zPuAGjh}0NQT^>>$PvjqGqWlG#>eU~!kq<*RUO8CSXpi&!H+~l$xHff#cLi;xFHJro zwn5b9TX~c^kCm4v1?N5p07bP7wG`0|w_pU_ADHooXg|w^q>&QSVt9NlW;6`uSsAYsDG~~fEwmYtl{y=be+x;ELn;yh1Sk6oAYXGOU36< zDdGdzQ zl2-d^skheHv6%cwG`z!>VvdeE-innwx~#%blhVbXqgpePyQs@YjrY(Zs>a&fkP)M! z_jChrv+eI+&HsuuY_6|P4i0?pzueWUb>3fm034zIzsJQ9*o(AG;?Ma);?8@QXNF^x z6VtP@f`N~`iY=UI_nnQM4v@uc)l@h83O*%f=EdNNmFp-mg_+b&44dP3!27)he=&m? zKj-=g+}F~TFz-w+EWNeFKNf!LK`=Ixll}T_0#$uJq>2SrcS!1~ZyOwLK=h}PKqJmO z6i_}M0aH#&rrBO9*@?HltHgV^Vy&AQcb}elo>4>>+>R`q@J(3tX)K(;=yblhlX&t5 zKC)#|My#BjqmZJQHrWqMTiSoWL8=VG6j=;UNyNrSBb1<5WM>z635r-e?WJd&yYalt z{>Lv=$Y(Jt)@y1g(STWZ$`uSnn7nY*1Ca1seyAs+oWJ(NTkUJ zUO=yN$!k}bqNT$9T9?iH2SU@X9^7NtY5hfi=d&mBI!3(*-=x)dR5o5$!l+jf4X{jX zwmh$B0@1{?`e^!G`c)0CA2`K$Wqst;ebwEXXpyZ#h7lh*=M21muu;d7+Lq8Lp0x3| zQl7TK1RpS?TOvUDdUUzI0=;`k?rH0rQHr?~AH}NJ0W54k>w1~hnP~cD5w@$+jm$w` zKo2Xn&^UaZsAudK6Vgpw*?iPJ(lllsrC^&)L@zgeWNL?0a@oeAuRqrP#^HEg$15_6)Z-|S= z7{(Xiqy##EPBF64Fydp{KbBJM6OEilIF4(0kAAdEFa_Ddf6LkKWggFwYc8)lsh;Uq z8bDsJR$VDumg>nlTG(Z+P%&tmQHGo&oy11@E zjE8y*9ep&2v=r&1Xf+hS069g)4g2p5G$aLgidpOo)y6Z_19^%a$Sh6@U9kuy@q0sK z!9ooLBbzcNUULHSYlKj+u&yih)fXwii)NS9k=TvKZ+=+Ci)&X-s0+^IC92TQ+&#Q~ zYZo!Q3@2a`u*Xnw$sZ*mkM}a|+$agqF_Uu-(WDup0lD44 z*8L*)I?ME~_t&!(07WZhJ>}w}>$y?+ZqA0e(N?Nklk!&feDSI=Ny#x%n%C4wMiTy1 znbbkGp;PRL3hD?%@7F;w4V|h(X;P8RfzS}I1M>}F{>W)m0Td4GSIQDZ*=Vjn2~H{8ATM+2Jb!?QpUfV1&loY&QwO7R2Tl?w}u zWvxLPtfoVzFTE^Aw;i&uy8}Dleqr7@M>pq&0HN*O7KDAl$J_FQ`a@u{VW@vN?u_qp zvyO|cMAx?kA3)7%;8ldSe`%bfBZ!^i>~Z z2TFgtLqOqQy;SvMU_YXzLH+AZ;9d$5SXDepmN<(sea_qN(Jn~J#OHX|$kw+G@RG8f z5suB{QU9xd6&0KKz*qzIT*Pc$`99upQH#JPw|m<&prbm6Hl`oHzwu$BQdG)=g(;FM z$cxqZ)mxuJo1xXx4|Q(~`zytff(R%ce42Fp7DVgl?69ft@<9NJ*8&4+@5F+DFh*d~ zQ*wWHd&>9WWZjDqyKlg4wl}ALr&?_LhAt8#4Rk(bsA1_tURMcn@}aYtlIudw&YmJ* zxCa^vpd&raD5@{u;oxq~VbmOCdETaVIzt}bPh49>vZl4h_7kZUna zgdO@M)v8ym&_5G_!2=e#GVF}|^&9w1jgx4;zIWJHEx4_TlIh8Hp?yb21dB9sUcpS0 zDTNp8R=&#lq!s{rGb^m-&%~MzzJ3YtjTj?ezsIe808G z|47$7$hxHh{UHlMth^!GmbKXW%Xu8yI{3>)9b7XuqK1-!nGKr-$xjqFoXwrFoLvwN zRKNCsln0Vu&Y>6zQKwEyaSq`~K@XaUdV(L49%wlQ7o#B$*Kswc;PQ5|(6f&L+_z(L zBqaK(EB%63KaP%TaU8PqMt(s^iH{>hFr=}c0y_jkRtv_~>Xl5^#9t^oVh3F#AU~*~ z2(<|2K;H%~A8Ju4&-SdZ>3iN=&VPZt3IhEqGKJ><|2@Foz*skp`GZUUu(JPy zOCuz5jFAH~GyM;>)2=O`A^RFJ%G38zFXK| zk`xg-m?mOTyvnYm8=B+9tvouT6S;F(rG~x8Rm_I{9al2BQmOX{Qqu#{U8lIF7Z6$QkgaIln6wKnT(N9ueYgDW;gjDzYc#WD5w)_mXuWiF zczcIdsb$}bPCU{Lg(tJ#?^f1qh=y(>!~f*$YMQ+zyI`qq*l}N{RM;1>tgc1pnx>_m zoU>Y`dXE0EBGZ`*ty5TCGyJfa2E84b4!OmrW;~OL9iDp6lq@b|05I#yhu`l3@5EO} z@jx@1yR~B~1RrU>rcyOrf8ZujtE?Jy1&uj8Gz5(?#xAUL6cO^DRY|PjSU^>|mkA4a zvtL34JGK3@?$%X2Mng~Sy;v-nafg-u1+MYc%m?b?mCYTq=) zQALZ9AFR_Qc7b z^PkQ6s=lgT^rm~!n||uXbz`gak*~>L*Hu&h<^)o!<1u;->;gyF@npv2T#xN%r$MowXNm0PJ5D zBp#c40b`sq;|#?ujgpS-cV)|lmdsT7Y=;GSO3d?My+GC1M|Eh^{Gy;p9L9N{;Cc3n6Mf^A zUZ2s^Xoja?HzVk{0))HIJ~z|@<5Oq9_32W!k~vw{3DUK{V+s~V3A>zWk;6zWq({No z8n2xOOixAD-CtPw*-1W*E^Gm5F8@fW*XyAI=NLiX6b{(W&DUJ$FjfWm)K+ zsqhz8v=4U740Lf1^YP*RZ7xRS&elneCS?bye5Cm6H*u;GX)*iw{YCx#=WsD zKe&f{yCxm)6KbR8iK~xi=7vj*t*tYqPNxvoz2yKw55IHS8-8dpwoMgz4CCBmY^-n% zOuxCY0S9cx@e&wdx&PHZPWmXE1_lxha7*k&8^1{))1^<#$8VbgteNK{Y=@o2#SygG zbie}w%QrtQ=Gte&(r91M66!UZ(jCcPB|ON+{nDpiPRz;k{1qkUt{Bc}6jo#}Ml(w< zS@1XJmuEPlwq{^zXF>H*sd#$qW${)KkSV6a?cWOc8l9aR8=bkvLvj?HiAt3L4K;NR zTOG5|-)SYnLG2NYXV%LjzE@_uPxs=4)5zh1ZIcR%ETAfb2bMlw)Sk@@r=@{D2NReV zAXgwe@;vEe3t1bigr=q4(2yP<*{a@4u1o82Z9$h=ZLdLm68}J*T0ze8`2MgQpF5GY z6!tnmUGv#V{#`kC5~9)U-1N!=K%81~24Z5c5b-~Jc+%I7u9-ykA?CG_?mvVO`kP+7 zZfkOlwE?KQ{0`FNEMz32w#@CVU7I*<@YL%F z6|<@N)tu&P*flu1^a4`X+&bxCP^+TV2<$QWUaa@I^TKY!BqB!lkgQMv^1{8(Y44iv zo`a^JVk*hs`Mc$jD zc9vjjo&~S0N{g8wohXx#Z%2(;P^MTGl|cWi{Id57?L6YYoCcVF3Orb-CcpAcBE8(Klsde%cKWI}8krbV>YAx?qGf zC7cZNfh>i!5n%F03p2paa-eI5hy zfKvOkSW4~x-9kURL$T@WjmI2phm`n(f{j9RMhX4(AmZo;Q(#8JXJk8T9Dx{(Pz4yy zcY+Z~;?49TB*Y%(oq>JzLVYu4TXr!{J^BhWha)12L?8`e?(6MS-6;fU8or$ft6vM% z;9LLY12N-oI9*R+v6#`rN5#cEKR5!=HKy@7A7>%N+`!OP(b4g{IzGTe{-FHp9iUuV zUzQe(yNicI^CZ72;)av*1YtA~>@ffeQG^OG-f_0*dq(*AM(FzaLVNv21e)4w-tWO$ zqTnHKTDL#o&JRA_0p7oK1E5=c!gQwF_~@0mmzQ+v;J+qlS6`Mo7nd zMtgLLzZf!@M9{Czuu#w01``QT*arcIifgb3CndE_TZRI@TNy_*>}%C^Nn+!)yg|Zr zfB8)5`M-=(05DgXFgSt2pt>JWUtvTeNGRdY;Zj4U#?(wPY4V!LEa6&1HpcLGNKCn! zg0!UkWBcE2(=+AW4ijBH9;FvcBD)wo`D<(!WKlG2-_j~fd~h3 zT}X|A>|4Svs2>RKEeS|CA#oZckuVe%lDsIQk|-;Z$Pknt+6VcI-k3egw~5FaCdX88 zIO?CkDWT&atB|PRcUkbvwX~-2<0$Om<9*_Vtmp*VL{wOHSfemh_;mmW7(z3F*O*J{ z8Npx++$8J!n$7nu+hA1K0n!Qye5@`jv&A98@#yr8B2C#h--HBo5r%{U!PeKzp?kpy zELI}t@%-Af3C|g(Iq`#K)@s|%j^6t<7UCehi5j|a)NkMi6F^9G{a z#)uimgx2K_4Ki9uMZ*u^RkN6wK6%*AS3uO>dGjC-|3cxbN~}oPl(04I+`8$^^9=hR zq?bf+UK@%6MsewH)ZZ@tc(CAKMJ=z~e`j}eYM z+pXH2mwV7RNO+Mi#r{RD`14+ZHv?vgu@0}(tu0vj{x2bWY9JZVxdNs-w6v70wuD;5 zel2g2X%%B5@ZaaZC;R>8!#-Fc~Z7JPz`up^#h6Exu1$1JAu5jguQpL0W z6bBvfm#BC_K==BfZLs-l=+t;cFXhU^Lm9X&DOKXhRZ686ON~lR z=UVK{#UG2#*U1{TEy+bWyrYRfy{JkAyrcVMGo1w{z#Z~{{RpRc0Z%>(GldmGFBu_^)yn?X*hYkV_rs;)8>7qi8w;n;dI~ z^mPbc1ur6Cr@3W>&mb`LGKk~cvMJ*O zjtg%j^v7>*+ue2josfj;YHW-?rP2tIj6h7j=mF6V^_KMr1`JV4j*}LMn>O3iK*bX{ z>1m6y(9Xl6vSKw5s@#QKYFHpr8~i@RqIs43+Gg0{RI zR7|Y7IhBQUef`X{N~_kQE#JLE$l(}+-lMk8ojWq|xc}0FOO><&*pFe|mTUHW$vs!dIXH#C*q>e5p?8MOG zGL(OyaSojI8_PI87-3Mn9iNT=_dLu$*TQOr;J>)6su`(}$x;=pA<&xOei^&tHtEiY z(;^Qy&F;tg>fUViHPT{&ym-p!S{f=!9nTMd;_BSpcoxP0iCv}HQbMQ#oIk(u8AZUm zXhFETQ1jThiJYWU^`WetA7bI*p{U^O=;bUmq)?%oxntzVWhZIdoFU?Q zJ(%r>_n0N4(MkME@?tIz=QT0SE}B8XBj+sG`!cHow%lt$IL;?@`R{i`99c|xi@d_HUsuOIq!XQ#2sK_!0lM*7 zzF9|pWaSCH{-E!P(*ZMV@UZyId!V$#ON~^LK1a7b;C!8-MJYt(Qmm@uCP2#_EPYIW z(;Xix)(J*Jo2X`6=IJtEp2B`0SbzfnRY|#TTw%a;TtJ28MwL610RufIKK7i?_KhQ- zWf;EPqV>~&K1>n=9Gc0bVmh1t$ZmZtqyAl*PsYtNQl*4h{=TQvcex?Dw5J+&kuhuc z3VtJ5l|F9pfS51FHdxiYTwf0=f(<~BtYHP}yhBNOwenM8rHH&7b)1@U-WwetYueIz zWgA})JZh-H5`#U&O;_b}eTy15lz@fu>i*VR9xiGg7GIa87c?U6Sb*vK$JL-W?v)II zT9~ z>{X|rpRi0Bzjy+*_Y!_O z<>Ol(_?)>)`WJRKwlhdtve5h^HqtEq!&7B%1UE?7_#mRSF^+#DdNl!TU%;j1p7Ov= ziD((02L;eEq7{~V@xV%Jvbf-5bH)Qtcjp$O5GK}8#08hNy09ed-_e%Q3zx>Q3f%D)oD`l&ZivKS_jBcKDYLrl!N^{^ z#6JB4v80ibqDDiDp@M_O_WSG{pfxjxmVqPBLoT5fQa+3wTZUx|ci7CxoL5$wJoY$lQ*~-pI8Aj~|Lld(zrIR{VtwwmMzA~V`50Yy5gmTa z36~o&w6ho9GQK5@ zkA}P{Le(6A3j?`-C;YLa6iOceuEW^|niY26ap(F^10ge%cQ0VoX!-s9R`|V1I)u>r zT4_3L7dTJdLOUlopXx1a=;sP8QwjcH@NaWP>=T{(i1ZuN3$)3Kc?IM1GlN&DGn~5c zrm-PO9F566BlKz#K)2)Z#F0lUg8dcCu@Kz_D$;bBco`(A)#p5`FNEqsg< zwQpbZkxx6O%E^hFr$>swnlPEjk1_3T1GX8!UnSrvm`x^AV1j~@r~-67Kp}QI@~yE? zOX2y&2wB~qTu@c?_XUi*4^JE$3y>Ipm+ANxAdPJ-o0F<%;M(k_w51DgUv0s8`Dn-# zq8_o7u|!Lk?RX%p58w88zNTC@_0}9>WRP&gx|^IYmZMWQnF{fi< z>&$-VX7b=g{r4a(stOCl+L*o*0qq+wEB4S5YVoS<=|mfYCmQwnac^QKvm?Oi4#!k9 zrY_1#NWAvlcK-`QO3%CVN|^t~yY~_hm#+H^ZToRk=D2jXt@8crkk@!k!cqM-Hu{PF z_9BkuyofzzUKEJ`PUO$-sBw2{_>%&lvaK#DX`T{x+Q(;#N(-jic*w zR=l+jW%Nwt*3t}yQ>nAJE`n>}^gwe$8M&a3!DP!Wr#2~U^^txK=g5DNVL%_@Q8Y5^ zjy0zr5UH_u=0Wc^Oh1M^D@p^HFSW$Z2*T|jBBr7ryqU>mf?M1vAXfD!_uc-4?6wGU zj>%T5IWhmI(%ro^GICBMR!H7EGw`ndYrk`epgB1;bf!&tnRP?!V7F6K3A zTehQH1uybcD1IPD=9#)j#Tz20vUk%xkn^cwn=_ow0W62-+-G&B^$(+XkH`Io4`BCY z8AQM(lfEl39&J_X`8VtfmUZwSwO&QSQN>H&c3 zuwk@+`^CTX6?o~F?{~wthq_>)(ldMm@^OFj@qP6~3Pnd0Pet70*)NaV4RcQ%vIAlO ztGEoLa*b5TUXNoe<6VKw+`!lzSV^k?enP7Iq;hm26f-QJJXpGQAFC&p%^r*p35K%{#CnqoNDOq|C@K zQX^Yb4=jn-!68WZ4ZJ=k`0!q`q671O3=Aqfq*cM%{xcvKum703>RRZglNh{=4=){U zd8i?0hStxa&adFj@MS-uWkBV#>{?2sASS8f3Rm!_CaWHkoSg9f;3}92f@duQg1UKt zdMnO`H^N&Ys=fxq&wNZ3N4*(5S6jAn7TvY~Dr=wjw zQCzJrl!Y4$n3qrc@M0po8_#QS%>E-xB=%t4C%y1|618G^a1A3OiIUTJ=K63>p`^ku z5!C0UI6C^xeD4fYdZiZL;N-a><^FtkO3K0C@Y>ogn9BiBIAN@JeO(!23$a9cd$BSy zvj|%T>s$XP_caOE=e!_bk8OP^(?6IhY`Q~LjZg^>3kw4STLoWPTU%3ea#sjQCQ*4m zavEnN(uir5G)UcR+$$QDRnqIaIEurfO=m=l8zIS+7f!gag}88~)qhIW-5bBqD>raa z^uP>{dWHdP4{O?=?y)V+U2GX_+vawLg!$9zjt1qagvrDE1AQ@1L{s0ueW_>sdN?>@ zq!NR(LEWCupNc(73VaW8FxN^VRl!-?x2}pzVpH0R31u@E88o6CnKnr$5)U zeTuS2#!E*OhEThnPd-hftH)?pEfxDGH}w0Gdm9~QZhYett!F6GJ}l2k(vU*8tkH&bU3bTd4CVAfou zJ;kX425|WOUTHJsmNUMYa9@Qrg_yjJyXG!LmT0UTq7CwNtfjGHoDi29@*_%$sPdR zGyLHoA=0km`!q76k2)FYIr{qWtk`8#G^uU4+*LKEh@OXy4AB*Oc>R1`%Y7PfnH0kG z9q!Snr4jY%6?MEZaA@zw8u9v7bmQH+nuOyMJ#a8shvXyV9xayW<~~gC{MnFrakv3t z4}uV$+TPqJsAFZ+ULL2&#&gF^?LGkD%A$8~29ErS_fF7}ny4y#2)>fHmy(OA)U9;^ z<2~wGTOJZ2wsDJ-@Z;EXw~#paOUIztuVrr+GH+)c22MO3e+eUS8OI+-89DPt>zoz& z>lT4EG&`Ao3#xV019;PatDMv* z3o)Pt6KvWmX)(y@v2f%`+i|lNV@X!=jwlo^Sj#02GC=K)Oe2=HY)a z?D6spHO+Bur;9cB&EfHnw;meq^(;Z(pEg(Ui!JhSuwB*5e(UO)y1#qFdG%)Q`8X?` z{df75vVopzcfPO&z!>8%Xe>?#bY^RePi z2TrD+=&n0OjbPW21~fY>H96x_dWTey0mp} zV#kj;E%)VW-Ts#69AO4n>%oPSjc}OCF^-hW3=Y=f*6ME3K-7{P1Vg?%FWzHC&n8q% zoyB}J+ka!BB(Npp6dQ13il$1_zg(e0canAkPp>_utRb-7v*yRw_is&uG*v_mb2{F5 z;%zx#n+cTr1ta41w?N{hz>G+E5&Zr*ASEyP@Nafy)k!HH9~7m^qkqu``1N+^#5!$` zG<^Wee3%9NvR(y5qofrUL(MW$HvtydQ8!OWcR)9~4}{`tXE{Iwb1Ib)a9`BHEGkYx zgGT+U&-$IX4zCo6D$)?V=weowZ+AF+Razg*XoB<2itCZmcs{2`KvZcxeL}cIHBl>R zynyjqNJ+-_^W@CrwI>mye|mTIU_V%woMXN%hgOl!Zp~mBwWHs!od(Ec9XZ+u2u}u z`Lg^)dFc2(g=l5To|gKFByRgI!nAAb-^=aaFA`(zS5k8uQ-C&MS{SABu6w6TuU|By zXlAzHJ=>q*hoOO`$I230f}T|!tpBUZ?w9#{)h(|)y)wXhd3~cb_Ge>)WVz8_tnTwcg(Cn%vbB%DV`z6?XU0rdP9(BH7tTLzdVRYy^!LHHQ8k|PPnQ^ z9(Ptf>&#ZwiWtNKbeVJv1dHP}D!=0IUsiJDdYjNR9z5GBksu%t`%B6Nk+UW&Xs^KQ zN)Ha_X+OZ~5Xxi*Ev(wnd!eh`2ho6qxYiZiZ~Dl|CGrR0Wz)OOXB4Y1tk&>Dtk2Y@ zPbU269x5IqN}KZ?CCgKR>k#k<5c+Iorw|`EWgNT$wkKxv#WAa!ug}p+>k;gX&B!?H zr%Gy4e}y`Kx{ODUZQh9jcG;y3~UiExQC$lR^`coW~z|krkb9+eT?0U z@d8{=qpCo8=?#=B@FXX}la-bVHE#&`)VDb3YXQ`M;$7q4hTw@Kf0~j-#U{}1enX=( z3?&0R;JC@9_hKfCXr8db-di`ZJ6Jqe1zMs%cqQL4?vDk2gI4dGSM^vdv%nYk>BPCD_!d@KTLf%*Jb&#lKPy6_a=P?lE zjJZv^2i>R5!r7nXphxN3gq5cEXP~;YwvWDtqA>r+;OIPkq~?_B$R-C*whyHDg#@FkbqRD}9!H{LZ>bsf;Tl=<%m z1gurRTV?+hxT?zuz9fA}o=d>T8?dgJlD;~+2KWn^dQ`S9ELjAMm9~bN;|Y7RGp5BkXNOP_*)bqKUc=fr&a+LBVH^g8x6=lyUI>O z-9tkm*y~QOlDge~vr!8CL8i}o-q683>NYskd^Z3AYKN9Ymygpt)Y{0IXq~JBS0~eY zUPR+DB-#~C${mw1j^yO>zeKyGrt{2|?Ufp-1g!X*{k3K3@>7&2%h8skssBJ12$v~R zM{h{}rldoYvdu3jt6pNKP60#~?w6}l$4Ivl6DFoY92o^{W<(MR+9&(+U0xa4svlIj zX>Ha2tLq`PFU0%JrYCP;uD+qU4z~HYUSY%5q7X(Cnv2&TbJ`5k{O(wEBWd~_`soN^ z5JntEfcsQf5;uYOG$w^0aRmYX2lBcAHH#SMWs;@0rUT{! z~_-_HCW5t%Z%N>kYCmTM1E*NyWqL{@sawFT4qIW8I!YUbYnAhXkg!eaD z%MJ@$5!sWXinHr#{1O1#7vI34ZM`Y(y^74H1#!Hqax_HCqbp(B2M>3#W*dp8)5>GT zoo3^f1(3nthOi9f0m=yd@AP7u=OBo^ISUB78@C3qF13asPrM|VM!2BMQAhAst*gD~N>y zm<7AK7c3OC$Mgda@3y_Ii!=yADduG^od%0<2&FEj4=wYN8d~y^8v9QxQjD(>-+}RL zd`A$m?t#V%6%&9lV;{Z!2W$8>ELWgT$KR*qXzpx8AN~>v|BPYnTbe}4>&HcmV#Oxc zg!6#}s0h;j1Nx;uityGgX-5xd-4BXu80AlqhN{_O?W)Qs0Qg+Gn&iBs=L2$oOJq>~ z^bStRD|pqPy@%5){oiKE8`D+ez$4dBuLjIsFrcL*a^5_Fc_NpogLMcjr9tIMVJVIMm} z+)4)6J22gzbTuTK2xjard!&(Ybx?chC^Q`*3WASukX;Ng!GU)_m%s~Ptc6@e(J7%T ztYam|Q(U276Du!yw=#%cbSpuz!N(2vx~m@utsj8gTL6iuMNK?1zzYaoeL?uQ;5?e6 z(+a6$bVKzgZp-#D#(XW(OXASYZ75XpZ0CoJrHSDW9BzA5D)3v;82N^(A3 zIh;gBC6A}~8Th&mxwN&4=`Goux-w6>?H@jLz9OtCqQUJn(?TW_j5q+cE~SPDMT(I% zn+d?~eMGs#03q29ESQq90Jz_*{j-)nowy3Qc(33R+Cv&YC9)mjH+1~Gb!onXT?htq zE%MUt@k~*{>8&U~3B5GNuw3r;TB|(d)t2Wc4w)vw$E^nfpyXiXPU5cs{>+F?%pWUu zEUR{K75yN=^B!olQZp=AuJwI({@Re|R3d)YSKIkp?5@W3jgY#rvwB|E9 z9Ofl2TgX}Vp=%kK%A7%?);_H-90WTXc~s-34!ZG)=nq#sr4RXTgL`B%#af24{%^p) zVQYy71_sWN#z_+dh^{dGlYMqVl^R6lv~~4z+HnCz#i2&GdZ^MF>~k)Mi*8@JXn_nR zdR(g785*{AOeZ)kZZaNT_8#Ku{QQE7*iofKw0_He)tpa8H|n>?L#fBJ&v#3qI-vXh z_{i{EwHGv-*6XEmnbdhde48`!KZSte;27Gs?!&$XbrGrQt)yF;ecrXvkA@20feRrT zR;ezep5pb3#I^!u2Wu< zJ!Go%c?Ze-k`uGi11b;x6LD^6iiI~sT9J!3M0e8_NCvNYHgif;r%p0C9ONNKPBCTN zUCe*y1PM-r@!uWyo`?;kn{X4+_Y|4p(G7}z@l=$h2hd^ ztQ<0>J%P{P*A{wAf zVD1Dzjm-~bg5a$N=ia@6UW*(Z)WnTjtn;VXpY}j0yXBM&aM?BD4Zd4@@E-uoCe?X% z8Pow5sO{Q!_GUStb>09CwL2>MOaRw?h7XDC+!cev8r>MJHKHcE8GuDkf(wvd*bsaK z2x=h9nHyp?P_es!AIkT-1+O0*&vq`5egCGxa}a1;whY=LVhLlE7TD4%#r%4t$;Vwq z%{hKerFCbEcv-Ayz(ul%oa#b^h9tt)FOu+uE@IRhW;!}c;_DjCds37lGhO_cXDN-wu&l+qs zcRNjPQp5;Oq1_P{Ujc2s)@QoM+I(x@V}(nPmPaGUNh2f2=kS3bGGGi%I>sGl8u)|D zqv{K;1z`X~wuc%8w75}@aSk*H+;_=!-?p1kp3nHT;uM83iBPK=_^WC(!@EBzW;iiF zRJ>ip*K)L|$W>>L`@gHB^xPf!+)}4n?z9l5P|p$7)lw~7f0PJXh1&V;w%gV{?uF8l zrZuqVw@K-N&yat0g;QFon>p(18zBMClYF))cFqA~LAmn~_kMx>+U8Ur$eHo#mshE%g!5HPW!rjLdTQdd1rV;jINpTmK=I$ z<#p;JHbc7+@w?9qFZ*5cMK()1n+HqOp4VrNqz&wo4zb-Ey)k+PI54g}@H1^FTLySt z@-hGxPjG1WWhy6gLN!obh;50dcBXEFW)41$Ppq8mO+4A;Y(22z_0;9)1E_gUy%7@k zmw`n1y*boDSy@ASo^q$b}tfK&5IU8?J_TFx+tt!=lvIpZEkwcyU-bH!k znN~5aR7ft-q=pDetRl}y)BS@lu59@c?smzbuC_z^Hpf!Y|&v z%2JniXYi5au8=e21OuS@!fz5`!N^6Fyk%lojP=n36i(`G4G5-(LS$q0Jep=+)&u}B zOs9x{29vxdhhxDud0^dr?F(Y{8~54U2?fL7!>~Ln@Y(gN-FZLIk)~#zE#Q8XU_{Iy zL)gi8pP7~d;PZ3F1F6Nwo{}=^j@?L)J?aBp4XSKO6ljcmq9v;$c#3I zsi@XV*8TYdmjUsh{xs{Rbz9a;a(ciJ6H7Ii+Pw{qYaqF~tMVW07y^t|^6xRPJxfPl z-_is=h3sf6XsE>z@b0@8KE>Or$iP<)z{kkFAX0Q7%1lk9%#NlXcOjsrz3_Od zz3x8Rr>CaAx+%HS-Kyt?ciQLMef%lydi|G@~{_Xe7nE1DG$U#V%faI z^Y-?@>+`&jj2C@ww}1f0F?Xf%LA!4TsF6$=iE02pt4el>;#7}k8j`>{;38mYFRoC^ zjrl|5-s*2#ht)VoD8R6=rWE(v=@lB(8RF{j?tMZLOGC-Hh91d~ToQ2q`Rg@AgVP)1 zBDCQUSUzdFU6Vq)T{AP(fn~%Bu0PA1idh2js6rry8Ryp}52pWTvEeJp{v2x#SmteO zycSK_4O4c?{rk~(J0#b4(s(Pz;Z4oS`Gd>^4A^a=deF}9d8&e4Y7b2r;}KiB!6c7n z%mh>{M`(guMHnnE#4!M@4_#v|&~Q>SZSV~t%PUlPpWOuHx#L&JKE6qbel5#+NPQdT zqJ!!eFmS-i2BWg`>-?hVEA}3@-0-NLR^~A!~r7pZbD0Bzcwl>_!i4 z?}S|G9^{9L{!b`QqpE50Y%7yY9c#JW`i36~jHOeQ?7jB&H^KD_D*zMG@p(crJeuAWx2;DL z@HX4R{WCIoLaG4HrziSHaF34jTwnb?)?}`K?`D?%Q0E)7IAsfsJe4z;Pao{oL6@oR z?p`w2B}Qj%WhzW9)QoMF9P12#C?co#+;PI;)604=d2^@r8;yDK226k3VK<}IgQkn8 zGd$2l-N%dse)GiaTW3Re6S12#GIuk!J7L^Jw))Nbyh{Dvs z5K&snr4?ZFJ5AD}reg@*Jx@^1Ah5&3G_i=f6b~N^z;|4-VNbummkS9QrC(o<_@!s| ztN6I!qf5DQYwY_MA;-SUe^YyYcDu-a`ff<6pD@5sP~*7}2tYp(Qu0&;SYSFhPDTdt z-%idhgiLHd(}+YixBxD$|B!{IbvKOpN4CIS-O>`XhqwzXv6)sKS z2`G^hwDP6UpkA2`1gzbI1cSgR7h*4^#K7lLw<=flz1=|(NlizXjack-$+5mhh0LY* z44JPSZqw1=$4$q@WP$RW z$AoZ-PO4OoN4RPmAaQ~bPn5v)XY-(AEW`exGRagGCu!BltWr}NRG}l#WE%@jb8FOq zDU}CVE+G@GEJJZ!t1J)Za4Jt@m4XRtS^fM86MbAhHl|(D*gi9~*ii1D9pH4QVP-k@ z_I*wzVrLMEN#;_=M}MiI01giji30qr-+P9^g;cNoTDW9fLGrNXq^Cnsu;12Xn&2R; z?W==j4ZFxKtR7%n+A_cv2bOa`m3~e@AWI)}-A%v*5Q&A0aUh}t2oElAfYGiIqg6kG zMV(ayn}-~ac#P4klrdO$7SV0pfg##JfE_1NZBvMcy|46gUjl_fjO=T%Ge8b4 zupyDcO!^Fzpe2JB3N%~_{P~VB3)-qQ5n?JTY>)uDfvCqsfmdiW?N8hvTx zTXr?Wx7W|vWo=nr9U8|Dcq@>UZUP%-QqmT$z@Hu}D}AyVU<})TS)@LUlkb4N@gF^0 zJP(&3umf~#IwVieof2yWz$G(tqGVf|-RLY)#F_)YMtxea*8Nj+(t?8`!`LbQ3Mzqa z)5LYRxj2EAKX6l~jxM!QBIl(sb1fR_Z zMNCAV&QII8Qh7f*6m+Qad5O+5h0=#P@Q9q^^8secZ07vOX>H>0ZB zPYOGI95g&4(c-eNAL{DFjkUMz-WGo?hyzj#rc)ovYRT<(3MpuSu{s0?!XLz^oarmh z;iFtEdJxRAXYEQodp&ZWQ(Fn>AJ~4g^lHiN*n3%I`bhgiMD)Qoms;?F5jPP9Pj=8&XszmB}d7JXv3NOHE@D4H!m2TioL1-HdU~4BcwziN?)9rX#%w_6f6hj8U z`?l~O)7pG>4VAl!<;7&BU6$hIJSp^1SY6e9+9Q-!bcHrI78-9pk;-Gmql?gA$pMm{ z7HFlTtN9&F*nHnTI<}pVh5lw#np)7B$*a_84ze>mjIrWA}yK0t>7c7t{qAgdrwwv;1L_0zzKRh(&Z?l zmrKBrRkGMCE*Wz9tmmk$Ywu0du@>l`S-&4P^|P;PWa=-M$FDo+ZLysDas(!}?ULsp z&i?`@LYyZ2|4SL-R2jm7J>)kks`*BdQ(Nvor(K>yieQ{EdMqeDM!a|cA)#Ci&w1Mo zEWMpBci4!Bw$K8e3WrtR3se7c6XjK3RP64+rHe+E4BIVUxrhw^EnZ_{G(r+DA1DqD zau$!PENmTTlZg`V-5fmnMdB-7Wf9)2F&+2lL>m-C=Aa53wHF@)`m2J*>oS^229wv- z2&{Zn|NH^OQA!P&NtrPKT7qR5A^3()#2E2^nv~*gc(?&s) z8Olq|R!^{=SG|OQOSKsvdJK}KbQuh4T0=E;`LSHbz&v@hQ}hkoL#t3@ZiKhw6E?&?hv2ubcA&f!r6 ziYuRA&>B32&#(M~kh#>hUO0v$6gOXp&R}U$77R1hJClL}Gm7nq5m(SQjEsbLAww@_ z1N+FxM2keZ;qjmC?Q?X?_lA)zq=|`@iVD>c8O_aGo4sl|DWi>YZ8^LNwQodoymZN; zM&`3BS#Fx1%xY=-GEtmR*U}nB12yp&8>nwOj0#x^jUylWL|LEZ1Up@3gPkk>^(o9F z_PQZD`MzqN1$+IL^kGiPMQduYVwn$(V!l-*gmJia{%c7<50{&n4D%ZP%}xbD`Y8nn z^%IKL*13essYI#YABg>7j+2I%5XP|I<*6xi0z@zsTV}(oL$>mur6oMpH5J2;XnmqE zb;`f=aKO_=r7I<5$WkMD$*?NKnWG_F>^QFMZk+7aa9)tDM!)tLtIqR{0ws&XmyjZ= z(h+UKYH>IL$O0G4Oa>{Ve|9_17J0ZYuw$KesNZ+X6`#)9@kuSetH#Vou4txK`$!Gxl&2Iy!^* z{zi_aM)Ss;$`(B8gw0!6V+lw)UMi&CQYqWHxW=>qz4L?cV()`4ZR3?v%tgqE8;#9E zPn==f@e*xi+jd>~L?~A~UwAp`ma#lAA4Tv!70>J1A@y!s$u@JU)e4iwHOOL85}Rl9 zn52|zPC1)r>YXaP)kUAgVGgpvRRcSxwB8x(XZW`ida8 zj$pp`?w;t(KJLoCCvf!TMS!1oYJag(wizX#=hvQ_e-n)GB+2`Qn~=4$%{TnV*V@;$ z3-N(S6)k_sgmIe1-Io)>&pFHvct2B6wzB{*nZ1GZspbuExA}Jae}$cSG!zOO#-lFD zNC?9fC2Ne`SYq5r%gESbLRn^pBo)^#W3Htz_B04%GO{x=84THt5h2EQQOsn$#Mqh8 z_2+la_nq_o|Ni-&^PcB9&-;50=7_<;m|mEo)>9_AUf>f8qN9D3dg*CTrnBY;pUcSQ zaS&;p9SX^@lCFfLcmX&W9bq<-=#Tx1G;j2d&xRo;XHaE(#kk9{YO`GWP(ie*&6R-8 zL+4I^CPBjcj{+64W5B4$C~th&#QZYDdEURbT9{roF#c=imy6UQ&9XTh z=#aT#u#q0Bd6p5{oITfpdAcE9M?*AsuC!mJu_J$@Op1*q0Bo$&#P5X~DJvw5=r-jr zeBNbUQ~g;@x!kuuzAp42H1^H{J@=86XfpV`fB%iHUcV6I$a9{^!kg{bYA~~>^>lh$ z2F4coEOk}i@PoBPVoZVHNbXg@Bl>-|wRDoV2i-R5eek;ht1f7w6nei^ zHEd5iw&vRHZ3N1=thEcWRbn7bieNVZ-$RP}fU(bVWt9j^TLI zwYVDJl4|OWf@-@y3%KrhH)jnsh{zIrdl-KTV^!lusb?iMuw6i&0yo)CYa zTw5LVoLqKoGJ8y^^g0X)=hxCQwW+s?gev(K1SRPdHH`3BrdxbIKIKV+3mw+#gV3rFC`_W;aL`FgEO7ai03^c3hkivsrG)b}RiskJHxRTRs%| z-We?r_@CFdrY^MBd-zhJZk=0BShAF)X$%ja3z>~asbc?1+iVAJQ6#`)!i^`hao1K& zk=Y4FYp1U9i#qpsXu2-DVQ&d05l0ev1Zr~yO}0vbfdE9n>~9H`+UOG)aVHxNq9WU> z`-N#tUf`SJHd8ggt&U9pJzfEe-5Dc?Q@gMIiv(rOV2J^HX~epgnyriP_-y6IFF8K0 zxLXtR1)e+<8+elM4a^KM`QGyjFDW|~*u`3WLrl?Bep&k9-W8)yj1W%JIhl;pKKn*~ zQ9L!*v%bg&n3eGtss$8?Vz}S9I&!Y0G{=G9r+?RlTKtagb_nVs7ereQmE;dBhg{6Q z={FQh@ItA|q?9KK9Kv?ltR3>{<$Z>KL(v&ZAAWI&IxeZbS0&vuu2qSik>qmUpl9rKKDd2$`}t%1&FdO~ZZ7+dq;+}&eU z&Ht8ja_9YV&Pw-S-q&lB{e3%UACLp;^U>Ijt9^)`%6W*sMu>n)Kw^i#Gwpny%rjzp zm(BC4nd!7y$*UO0@k4TV&vGFqXxP$K?qhQs$_sQi&jxSa|spwcKJXni#^ zxOF3(g1PS(go!urd?x8lIjxXl%fEA#;uLdkvhx-8#e`h%ISU#wbTm^cr<}cH0*E@7yuRNn<>+7RPuUx1hoDFcq-BWmyK|f|3}P%H#+`a z2r@@yPkC}GXjw6#&?B?lO1zhGb70ztJL^~%4n+@dZ|uJd!K7FSXEqY|i<(FX{7;N{ zf$-prnq8_l;IL5QCP4uh)bmuY`EdsR6*ZcE*RV_(Z@2R?_NIZODahH?zai$B$NMpK z+n+*d7&rvfHL~`LzE&+w9eB?%5-%^+PB2`VM3azB@oA;NjZAD2bz8L92i>?rxFSAC z{z-97^NV=CyRs0>m;2la-?{n?ZrS~;!H!j?&A63@r48bR4{0TPv(TQF16V1({kj^F z$|Y9p^OtiHp$xZI?PjMkDKLUL5uA$0{V(fJHxqJ!3uvmNt%uS@>S!X69vXTYNDq{T z9twp*czAla>!Uo8+7P4vH<6ijflK9un(^uaXtNe)UoC_V z)b&38wz=Qu|2)D(D6Jo6l6H=oJjMo|Z9NK+SwkGBW(>n)wii2i!lNwr00azDyOzl> z$|sy}uG{p9QxA2^rm*-#t;#?VA-3`#+r==d4)Mv9!r${8;(wwnPUN-0_iW{<6R^hb zj-qR>&S5hKxD`U}R;MlQK*>3b8H#Hks6EB{4MzkxhaulUZ@&Yf*{`7cH=Q{MD%8Fa zbjT({`}CZnd?BRP+xq7)aD?>yOcP4fU$!dq}aUJUVMd|j-A);39d@h|TS14TlPjC&~@M-uMXN@GFNlFSO^~IAwGWVU0 zcLb;H9{qgyAb&%F&dFy~RjSy3Yod_sL#MZY2;kI}M^o@Sj_}e04)XABVaH>%-H1th z!{8EP*}1IE!*&z|`}MxLQj#;-V6Us%%SrYQj}2_}HXUms1$`^OvpdpLd469|(Ky2R ezqisq!2QpFkUx)Kat$;zG&Il1%bQ!>IP)*RP$^*m delta 35578 zcmZs?V{l;6)&x3}iEZ1O*qqq5olMM$lM~yvZ5tEYwrx9kbHDd~yjyku?b@}gPSsw$ zx_fu6<2wL0)eTw`4g$11bb)X75M4JXZh_`r3#~qrPzwFjh__^&kqz$P;V<1L>>P{T zhE9~Gix5>)-jD+eMNV1HVe%Sp!#qp$oieQu4$6)4_58&t8H`}Gg8WF~d5V@1m;6T| z^r?*#^<`@F8=W(i({`0U^B?HM4YCLYMy9QFD<|7mn|H5e!zAEI(-3pjthq=CHLlZT z`IMc?C$G_KUGoGr!zg1?(ud}pbyJ+U$K((6<=+*?yg+=7ihUhKh+9*9NJiC|-;oSY zuSj&1j9g=Ix4-kmi*>*q(-B4eY_UDHY7B)X7GO3{C{T0Eh3O;o%96)26tCMiSo6`3 zb9D^r%o8j8vEzY7;Bvst$iI7AK{@A=%@p$EFONp_%m`^*X1=1`ez9ezzpvZ?B)Puk z`hz)nU56k?WprQ3gd4UVF-G>peU6!~XNlRjHVKdfzok(smAYF_p`M5%sn?^gFUwE@ zzOl9#*q^xa;!neE zR-<1oWwBf7%K1XAY?`?p2qCcR{=EjbPCuM%PJAXOD0lvyG%t~~)B3kz!xY%0ASfDA zAGP)?Il+&uL|A}VGPnq9B8ZcEV!B3jea8))9TAe$78yJ_7}C1(e$VPf_1OFBzP11ihiQ)`~527?Y#yYNN}lbZ&NQ9s_O zKH2O$?jzNo?rCV7zpYTaL(^yM1oSmhV3Lrnwez*s(?T1T?G!211_~b(!2Ia|S&>ar zOCp~o+3(yl^@9Vygqa;Ja`A4C%BUj2%dlCF34$~2lKN#Xp z0kX_)jDO8h;)6r5k+;eh!Pe(%bzu*{+dGnL;GO09PY1m^7Xsvxw9AJ`XA`saW`k>S zkSuubw7oWz<~nkdLq(AEqgKxv10+K1{iFRPJrpL&xUGK-- z%Fa$?gI4){X*w^St{(P&$rJVSEyj}I0ZLi84;@G&rkM!RY9(X(WS0DVVc*)WoQp|N zOr1+l`P8yymPLvj^gce$GXy*rFkY-`U-I8=jRHvaK#D2?1i9sq6NIK0B(ol zeA%#Q9$GM7OV5s+p)Qpd))KV|2vY;y1zXN!hdAOafunL>E^n3m5zXA+hwF!4JqnCQ zxAL=$tgfD(#7CR~extSh3ULcaG=xml0z*?-yP+HKHW$g5s0n62cRW;|Vgu?MjE8Y7 z@v2oldz5&optmo^Qw7T^#n^|hZ>`jWf0nLUk22}~>vNvs= z-&u-*3<(V=L1jHof~(p$Q=Y>vS3t-4z-_$h=s0@p?i+UAc>XO9X(o14AsfaOcwUL^ zS!9o0zguWCDowC?IK)d0i=+FNr3^#yN^L^YZxRHPq0Dh7DrVg8$8JFxK@UjD}(krQ@b^RpDxr_kt~azwZf}2 z?n5*&oieW{8EZP%WN1bpOcPWJ3n4$VHj9JvDt(Ao+yhVK8lQ$rM;I-e9x9$px5EU= z6sn$i$XEKfOzU{pnJXqBaC1&{XNofDkAAnDWrpf?!LuP?DKRMmajd4S59x&z<0&Zt zJPxToIY@Eo$UJ36*t0UdxrJ$QB9}D?#7=~!c;3$3oNHSB3cXtciqRX(;zRR;qP)By z5Cp}>q7i7;Ys*$FZ655-Wn<$)s$RVoqGJzsf4tCkdaGi|#?LpA+;Q6G{1%{z>vyQ> z)l6ATCZGhuvWW+PyK!kA*Ea)1X*`7QDIC~i=$Mk6#ahO1ULgs>wGeNJ|F9OElVu_q zO*4Z*;DZ~!^%YE)> z+5&e`6>kRZ085ewkR9T3BKh(z;D)9jD0!FIcGRp03H|O2(W4_hH|o2ebN@Q$$=nlS_1yg3iqZj*e%VMatTw7tKER#txB!!8#gmTH)O0rEsUpi0Q-|#30Dmgu7*p(5=S=ZHmO(vb8S?4y6kIYCe z@7g_eb`y1+V8nkCzc?q;^hYh_fCryKC@%}ma7H3B47f4Dav>?yt2 z54Mkis5W~azF)Z`@G-?D|=78(PJ1qMIM`?q? zW82N8*3+nD{)rt|xyi(8)W+C%7xPt>ttE?F2crTXS^)-Bj$dTJ1 z@qRhpNGnB35oWxy?k5@by&0|T8<&%P1GG+B;&dTWwg24N&p119l0)Cv0#k-ZY=qEc z>^{DejYN-keJW9(2A|){R=4dBR5Y#Ag~;V$QcDlU@Fh0SFPXDeBXv#t3nTVPk)IYI z?cil6VGc@2xpqJaA$-%>`HB`zv_g!e#bS!79PykTMX|P+)KYhn`b(yKe;|nIuNZ z5xE>^loWRDcs>!ipzXOV`&nS$L?%U(#rN=4x!yWE!h3*=?B;aP#klI64v@G9u#YjFH-8tTnC) zcB-HaVZ;LjyJd-LT7+xDUtC9^T@L$UGn}9(Ict(%pU`~buP%!^KSG>iG(#wbOw}>t z%Fm*s2ApeWRIUqnDP%g(xI~7(DN;4nQUAP>NY+cOyWo^g7&hD5*538mQKV}s%e{=0 z(k5hQ`LuIvN)+(FA6;mHFs!!vlUD@7c%_5FvRejV#s_PuQJ1@8KNOS|CsvQcAd96B zS?ZrEptJEbMC7Ty_bD;5KcVw)f(PX`$HMKY_^K=f3n;A2of=iyme=VH4M=LNPz?z1 zE41ff_Y3vzN~Y`V4>*jCTsjt^TZ}w=-sbftm&~}UiQh>;3$xs%a;LIjL>3$#V^dvf zUFHL)7QTXILG^UF{n8oJveeJ1?$1s$HJ(Aj?Iq5N@~IyB>BL5H=CZ-@=NAV@vyS68 ziH7DFsiw@zvE?+h7vn@S%*fmQS4Nm0rBu1%=Xtt%g}iy`DtVH*D<}1?1)YgyTjZU2 z$8@;zn6v1Dpy^KM0KK}Hf%EA5SLpE{=yTu~;har3S~|K6|KymK_*Efd(*h(t5U{CWBFMEX@t zhikC4fp)WHjjJs>$ILuorxqlK3O=4soDaWd+0x_d#fz8Vg~=F*UuV+$hQ*>vzCLin z6W?Wf{!zJ#sUYBd_?-eHsEd}U!`+b~&=~G~pts`HzLRmOMBo)e^vb965=OzZ{?IW* zOT9-39_Av(`I0hZr$|yiZ|=Y$1OknyvdXY{q<&8!*Y54(NbCx^wW6Lgt(TV0*)7Nn zz|jN0-##o$X@i1>SP1UNdkgR`j|YZLnQZ#5J+of>ejJa*5_k|+`ky~#=vO#^%tRtw zkr%hkhRSMg+2FUQ=&*q@My+y_Jv~9QtOl)>#9eh{V!y6HoY-f&{rLf(G3PjD>7<7!5Ci^&{t`B7Hdj?-P zehEM$ZlhsbvIoMhyP*ILe%h{w<8a_NotAr;7dXLM8BvU#*k%-L_-#r8S!uHQLSdvvEg+9PPlV#pREm(!R0KLUeSFYCDAu-=p`p1===aIM?Bpy}dL^>@D4a-B_QOG8 zy-8tojU-4-Uv1F!U+tCtKDzXZ(2YJ!p9>s`)n{6^7BC!ip?ZkxPulo=dWk; z#u7Up(Xv&;YB3r_x@AeU8cYkSpwwejJaz$f+!nVZJi+IW2gh|axwk$A7wuYC`+nyR zhjxx^XIfuuoNB%eSV11gR-n@6!$+qS8%_iLTR^6VAgml(xZ5JKv;obbs13RrnPfO*fyiPc^gpi`fu8o6HQfc%Cri zB<`?gVS9lFPa;h|l*%OG@<@tm>CKS15Xwm2$`1O6`&08OH@(v>X+9J=OF7Hxh?0j^ zu_vhHPhL+(O>PkZlDrrle8nBFFj1VNybp+w=%~W~2H*c-kA)!?i4q@%=R?WSG+|I;0#@ZZ$5l+12(H6AlfX&CLCEj=S!ZeBs0l z`84Kq5DTur-p1r~c3DJfUnG@}$B(F@1TX!l)g*G&a?*9oAC?r5eze8^_I}|79Ipz# z^;m5HI^`==Td#`B%6+WBJt@ecjaqB^vVIaN+}G{7|i=9i@mo=zihG zJ1P)P28J#iB@s_4#`vmxeGfx2ffJ;QgK8C~f@~EhU))P6(P;Q?QsZk_BBq5%O_UlV z6{0y*^5FVc(O7~}fOk8kMK7XCoRX59vi~?Nz|T-H0TV5uq}Wi9SLm_-Log~7hw5Hk zppMJEKs__`VH#q<qH@gc*x92GpRd57f4EOtL0piJt+#PFWC} zY>dpY?k8&#$ETME?dfhG>mTsk8U5k13mrf8j>I)l+b625MH`=4ofh~aPL~@V5a~Al zl=yK4D9w?ls{T=m6ui;O9OKhKr8oJ?=YeQ+{kr?CT=x6`K5u6mb&@u};ET`1IM=&7 zZJ3Ks?Tl~FDiI`MuGrqzOkj_6JkIAGQYjl#deg=@*5^0cF5!2^-mi}2gLBR0PA@B$ zhxp$tw}1f0-(rd6!Ie`{7*E`g;3ni477t|PNEqU zWZn@8vUO%*GFWKz2TvFUD2f0Kp)Xp?Cn{t632a(`uW`RWRdi}sx*j~7nV$0|uQa@n zE{S)??l92K^rWFL6(g=HW?*N08jWI7JvKg5L=AVc1Ce`7T-Fm?!OTp<{j8)I!w?P~ zjJ`_YX&1#TtJAnNHQ60{XHH2VT5d}Aadu7J&Dt!RD;s{=ll0(xBG|D@neQs$lnZta zDVm*1u7l^$akF9P&f&D(J1XpozfAy_@PDBtK9+zCVB!348A^}|Ut{>k1fOVJHdInp zD{*XyurJHMmWzH)fUo8o(Uck(;S6!^Z!Ik{pXUaF;!pkFbP-K5J=-u{n)grpIA6Qn zhWJyJUiQ@dxS6b*`Ce#~CtO}e2a$WNryEX}R{13I)Y;cQRhq4Dwg3RrjBrn7}+ zy9nJVBu@=JSsSVxOzn5^b5%E7+c>(eg996^N2)*3V-@T5j84|3`RC{AEaX1N?k~mk zUb<}PPET6+0@#B+mb{+JZNbsR-0(-qQfSsjx7zaVy=JsM8$yOC)WR>G_hW6#zIII~ z>*iYDweFSN>#*ncIHYcW0cXF^XVX%G6b%KX45@_CXd0jjmZoV^u^PxwBo%7F>x?yr zkx@U~1sp-i@ z<7OT1;zEaK}+OrCwL1txbu4iD-C|diQQ8d?x6E(C?A_H#tusQsL|&A2yd=& zqk;PU^E*T@Vk0!_f7z4&S0R}Hu}FMyDKZe=%YZoWk2g3k>%_k(pcSXfnR|^@*u@+e7 zyTaRm_F^;SdI-1%+)q5rvUjaj(@{DREcKem*N($o*N(KB>%1B+5^V~&kz6$n_XSzh zQqwN2HDZ501a_ED^QWd%y;9tXFMaLafUe0Noi;ZJxpQ32`4d7hi?xzKg&E3&#zoEJ z7W{&lhNWhNOpAj`yMb*GHU-fnLIF^NLke>s8Oi74k^3J|L(Y7WH`%`%=*9UDhA`Gb zPsY?h&w(^JC4diW`%V`d`$>6)<%4!H|vi7;lu*C^j(;peVf+N2LA9kn*SY4cX zwM)YfX+DA9W_%~rEg~0#v63|B@`PH(cqx@csA*NU7G7Oh<&G-BJ6Biew?FACxJD-* z14CZ=QRjJ7?(=?Ju3vJ{{iL$+usb+Xzcq$1H91=sagK)2hWM7MIWGM9)RLY;qb`q~ zeO5mRuEK*2B#b&^{jb|${XbD;V)(D?Nzk$UCyKweK4|Wj871GzN`3XkFM_}pty!py zqN6H}g9h26?qUFbt)sYJSSVa6wWnvvws21^t2I;Qa6KWli}jKy87+j%S)Jg~Qh#n% zYs7&vn=*yrFSVmO1oRinl`qOE*`JRu*;`vpdfnYX*Po-h$lf7#mp1Q&zP&eZ6fBi? zlKQ9S%~Ew&t#g~?nat*kTBUN8oOwfNOS(NfC4{p!?iTvH_H3bxpd#MV;3vQf7sld(}a6AyWnPuO18Opu&T;09QL%DzS>tU_`CaKw>119 z^8`0wloyLK3M)J}fRSi#gii>aI)~LBN*J6(*)`1ZI53r}!GJtLIKmtfgCs!e7IY^L z``_xmUpiDvFiv2cmXxlpsO6V=2!9bt(pA zeE=+WveSGLpy=n6zLs#uj0MdFu|xPiG4EK5yB6lCT)Ek=~MHhHM<)FNb6 z*;d4?q|Qc%q>^HtvC{Tz9xczVo0}Qa&1lyy<1EDzAJ~TbCDqF#Pv4_SM_ZnSKbUky zY};$`whWH+zcpR1^u3m*6h5C2{K`o*{}*D|{vqZE3nNo}SSdCz@}&a?)n7t5zla_9 zi21K~#>p#gwwrD1Y>#t&LA~ATZJkZcHmurLPunmqHycc3J6q=e*qbzDEqzdtmesKN+K;YkR}gB$$ciUjoE+L5 zZOZddOE8A^A~V~8lOsk?-;uzbUEt@vtvUCk0-%|L-o}X5?}+(p6Exy-2z}6f1b<6g z{zm%!0}jYyu|eHG|#Y z2Oh@z8z%-K66!_po-B%%3L(Jrd%J!%V;kvCY05TMFrh0oc}xFsfUq7a$}6%1DK+#8 z3fjPNqp%2c0SC8xB?tFwDF-)7T{&uhvEQrmC`FJGPEc5}8E*BB;`>JEt-&}$!QEgXhYg-eJ+R77#W61{6|Ed>9yuvA0J$o$$7zpcso;UFUO-vxHO#iog+cX3Y z!ulVEjNk5L17T%L_Wkjl8{qiw*LS2kls3xJVm4-+z(7evZrV(0&Mw{dt%|wjhP|!A zIyD_s-6%3)1s!c2Is5k&b`g*epW2WZ`?Fx>N}cty+gHuXriEZ@^NaFEv+LQbrwyO0 zmB&t7D8#tb_KY|FqxY$=hyVw>98%C^Iq6sP5h-l7JjBq0hKJ2zzX;>q~zd^B+u4n${1XwUw3lI zKlV-ta3}y*kdzehlJX63uN`^+mI-Xv`TQMTo?b3Exy;I9#yHK3GZgd}GF+JBZ>VULjmu2OIE5AVm{qFOhZzFtI{Tq48 z;iVs;i-(&Z9zHAQq*e_FwNQ@Y#Ask~%TLb0BVUdHD?cOx4mwz3Bm}Y`wfIt{;&Dc7 zv_K=&3?X{@V?n97Y~l6quRr2eR`Ztl__ct2&t+SRel#JI=oQi?yZDtsHv7WcMf0Mp zPOH_)$P#AJHkFcQ_)tB&Ce=q!vsEvTpKoB`5Rc^RyOh z2O^!Kow5^!hYBzy0}1Sn0h*GPIjV}~lmr&6jX}4Ci;6g<)(Jtgil54mXp$E>y(Ivo zq?m{TqcSa;9GRj=0jSOGZ4S@*UvBvm)THxRo@4g*Y?V_|nMChHhPfTB)a3J~cg%@7 z<`XM1j3LLUjSt?}EzBCPzmdMx2nHO$k^ZvOg5WgZ)dW^pb*|!P(*{EM zLAuV5E|-SAsgDLy?lB<6rkeSu0}6oZ5qOLrzj#W#VYrA!C&tB&YMQ)BBy{h|Bp88_ znjR0KWzwU#qL-1-A1ReV-%K*?*hX}f+ND*H&gTo3tSB?9K1De@>6XtGk0uldH&Y|T z+4ug&v2vK$z#*KRZimx~f*P66MJ3=z*-5Zh28i5LLs--WcSTLr#>@t=Ubwm21h)^&(Py~j zK3i zOG4JaN5z2oX2+|WX2z>ig*_t$Z)pGm8-&M$Z?3re+0Gtdb=VX@yTKSa5Z_OiLi+V8 zdK_fr=?^TBS13Pl{gea{ArOn9(wxoSpl&6$X)(GTkd9TbjydSVSV-O{^;~Im(3&fI z(g*T~CjMIR91f`&^taBbEbhI7r=>oX|4{l$ayD{c2oEOIugVbpGB@9uV%Hh3HdvD- zwXVMns}%p1{w>junRC+ax~_**t1QxOvlHJUL6b8JlYj++UcVNgSf(58rhm*HTgy?P z$xbfH9Dn&m<~o|nmSUk3m5A0MgAZk1m!&uS!mY!)!NfTy=WEH7-qZYjvw@2}_AcT~ zICI?05cfu6z$T$}EG0f;krIz zj)U$@y&vtn_P0(Ikh)@o9tG+y^3NhGn5Lh%{j4=CgO zN;#AaUoJ2%%t?;oFw^Bc(1G*no01Ff69a5`@>$s2n*4_nKa&FG3$S_TMB6ehk2=vt zgv25{N{B+h#C|+6N=J*W@U_nJUGmZPZ~}|-5SI45syV_7DYO zS(fD?GVnJnK5j$ZyWqd!lhUXuFkd0M z5G@o^XFnQ{P~{32By!&lsT9)5;K;Kh>J;OoawYI#%H@l{$M&%7CoH`RjvwtHLIP>cHYdH3!RT zoXvQ2mlcfar%IWil86KrhSwp_4U^pwU;7MzzmlOi&aS+8c)`wnXnbHyQNBBdf`CU| zU3O@yXx}-;P^^=F=9#%CdpklC((^P>PAK$a)U+fT@^-`-iqi4|jpCggy;X)>S_pMh_14$<_N--^ZY}CTeXkb1%Xzzr6euMCT6R z9Ut(vqctqw7mt<8BCqG9&81qIJ+|}8zoB+7?JJTQr+6IGYocCo-j9dhkY@%_D?qvi zfEi^A$dzCS2S{awP5c0^j3+932111#$cM(F(Tsv zhnTuTS{9M!!LB45%-^;WdOplZ?}-;EQ{Yrd97(stE=fZGGJ*AX8YY%&KbrF#;1e9= z1}T-3f}Tbzu?=d#-gr88s3g$(z3FM$l@94*ttSg?UG56aEC;Tml^=VRCw#* zQ17TTc5{Zvhnw+5M??3Ms!f)bS(qY+kZlzs)hN`yu#xj*C3OY-M|AR@J(GeE^B}*6 zf9ethf|3sK5h$kYWMVFodhiXlH>)qz4eTUnWCU6nZ!R*twc|d z;==j75_A)*Jp@@}v`k_Ln+OtM)mRw zr8E3&Z5zA$hoaC@x`OP_tr%;j!BThKLJ!e!cMXZOnS{T)zx}3F+%je`Gbga(kRv3l zXsP&EfkxYFx9ab;P6^)+PG5$3@<;NJD;rWa@6?kN4VjW^8!5YkFs^3N<4@%A&G_u5 zoqR5&R$jM=OsAIe_<{YiUKOG{!B$;Q{I9L&_17(?$GwE4OQMNRcN@+Y$#%=_T4X^6 zh&?;l#XSXA9{9nYoWUwY5%2kc4u8&b&8mzTt~WeeIu_GPQ}}jIlexfOn^&rf&CSXL z2b;F-gBu+7^_RpRPeK!m;GfHMUnk}Oq(lPx`jiO~C!m8iCQGA6E z#TOKM^hH#@X~69_4|`svR}j5V3hELcc5~N{8~<##^V2%miC%o%!`vUPoKQ~HWX^2^ zXJB?DuiDeB-27ydV-%;J;@MnB>jZ|2W=4X`&X=?kP9J>s&|eGomM1N3D2xPk45v%< z2Dq^&bj#K|gJ{^12TmMj$wz&YxMw9ile%5U{=s*T??6Cp+#7=`bSQhGHFp{ah;zW( zn^s>mK{H#Ueb^nc&2Fr?X#Z5($i0=Vh6z8#vzZ9WM#NB9u2?RNX=OL zLi&iAo5{v#^c2#n{^9Vgj3WPPPenUg`c8T>po4I<*xAY3&3BR!Q@j~pBDCo`GMCb( z)Pm~P7C<;id5o!lia>w7DvTa=^AvVct74t(uXb$VXX*RJIX?PuOZ4}nuvs)F26(+U zvm=F@(2iAYvgJ5`5-n+7)J-pN=w+?{!aW0G49Cn({TjcS{sL^|ECwe@6TAPI>16%^ z(mTzGUyZ81;b``>tK8m@T)P>2kfPBehu&V40b=TkLpusGbx=te=?7)bX9HDL)$Ds} zWv$QJ#ubL;3N~;Ed`@W8%bBr8(raVpY$Ihxo1A>114f6keQ|{o>0?jVX6(3=p4e}s zRrC6xF0@iM)7Hx7yIX(ZnHjbq_hwsvh$f`}9n8;A$A3eNOj1zLXF@}BBqI|s`ST}A z3*c)>mR`SbJ6K`%6EiD9Q;uXPyK%@bIKVz{BS)hEspdhkmf`sOLI5|Rr*__ww|^1G zTsDTFz$$)+F_hA3tVA>;*m>x^U};_S{bFOnZ_<%$8)bG}R1(FBKAbEy?w2CTx zs;t@cu(r}e%c!A@omb&~Ffmbw>r%gH257ho%yr7nHC1+t;Z`Pt;e6ra`kUpSTgc$2 zhAHvtCFF2iEgUA-v=lFFU&!Qpe7!X|hGLgCPEN5}d;LAa{`a|lUuxj4b#}Dt^YfN@JjB+FZ%EhSO7<-a%Y<|0zkV~ zzh0Ofgz`oq-{-g_Ja@)mAJMrQ*zEAyeYb93=7Y!O==LB8T1m^4Fx>N=wk2r65BA=V zr}0-BKvvK5q(9_7SD5lr`kEQaF2AIG2fbVF89QopiMryNzqVN@O>4+chiPG3V@;Ui z6W&BZTG0|0!o$P1hGZ$gM2T1d2ZqLR6Jje@Q={P>%=Wi^2A{1(s#3!Al04?4F~X?R zuvM&M;XZNW8Rc-WN*`S7q8h?=v%fB&W)>N~(e;El3pn75`XIo@$B`38pzdZo!)9-o zM`4{fPTQb+3`^v}C-~lvSzc_F>-)Sa@!*b;SEkhIF6+$AYkQ5N>*8e%0htyT!{w&j za^qSYW*>q8Tr`QDAFVY#6KSb)Sp5k`rCIei4-L7+)w7ZC!8u>kisd&GQ|p2w8!yYr zj`KE0TxQ&^;?$t6Et&iwy~y{*N47Q^yP~E2ah`#N*=L(Z!jrC9HSRu)JSWxW61h3` zsNDHJ&qe%-3#gtQ!?g2SfRH^vM%348IY3w9F(fEx3w#tgEG#0?%7n3uZg zAM++it4_)8iS02-3x%J9XlP#vp%X|scZ(ktT}e%@ou#B}R7@$F6ps&-GlHpf<{Ku* zC>VGTnY_U`!0_pN zG?JbOlkNV*Fkp-Xj(osz4FW1E3QDe}h_QHK>%`%h&O#zp7C?O~I)&*cGdRA3k63*z za~tYh`N)}H_gjja;L)$e$Hg+HFHA>I)PdtL;U0od?pUGLMJGk~czf#op1bm8_l?UxPKA>*br81~IB+Gv2aoK;pQa~TrJ5~X z`jPxwePJ&tv5ta?#-xAonc-@{${Bi8?qH&5a27pLMGp_DDjH$KQ}Au4^T{@wV_2Z1 zBr);m2u+t*oF(7Xo-h_RFIjmVGF{xSrD*8I&}>l&J~B^R6p`hqylhsUIQUB{E9?lV z_l0iD0i@s@AmOw*%{B2*iX{?CloyUu#-+T9SDgZzSkc|KE_Rkim*G> z>B)4h_!=VcHPf9s{5u8H3YpSVtTPgDU_`yuG##6Hzgvh-L9bPXOod9?LA zyyYL+kJ!0i2H(WN+4j>M9A!+E328b`mtPq*gQ z{zn?e`fs>}Jl=W^krI(X_Or!vGI|g~Pp$FWH^yOzt^aYJjp08z9l*-U%J~0J=mRzW zlgK@0eM==IgfvPZzsOWRQ^Y9Htdwf>3G?&&nMX+nS!WxI2>AvN(${tM27g<#8%0Cc zv&yE~*jTwypwj*uV~g9U+N=8uE+@CT`ig*XXL3E2^C{!X^N5=rWc05OG9>6BPG-h_ z?(I?qaMb?%ECT95-2kz4M}JFiPaYzMItA^TivLx|$3Ha%?FLo7HA8f%0<2 z*_%u$8DlEC`4BPjB1S$p49p_Nt2IE}%b3asxhMEA<&Bq=&WFzmCfs8 zLp^I0%2+uOy1z}VKVB_fx_*oJWOpkzO|QBGGdve>OsScP<1>!7G1_SOsDyX04@sPw zBN-LOlMZN{*o5gn5fa^Ao;|?dM)$jz)UvJXLhJ}cTE^vwqL(o~%M!;I_zAU(;%NMg z_my@~&iAk`_kM;$K0GQ6Cw%hN{n27;A3ZEz4Z;j4SOGpVy9AV}?2Y_)v> z{J=&b`Dt2vZGGueQMw3SofMxzF8?M5O<+F|difXH zeM1umQ|S4>>@FWwnWM0PxRjDwb4n+>Kd8fs6303LwnY7O3q9^s_*Eb;X0#CGxM zehNn&8x?9IFt^v^-ij;vvzc<*E_jEvZwN)3+|%0Fx`2VpqGRkiC^TOpcm(JSm7>5; zd#0Z|C|Z-j8IPDiPxWFmpD6G+%suo+FQ*m!IX~`HWP5u)q7h$<8LCv=!E!LJ++5nN z)uzR!<^8>>DC3o#^{Y;D8a&ZjYg8*jre%457aao`%McMetifqm4Jlu^RD2n7 z-d^75EX}MsVn<|Yb083E4s}93;!Sst=qEt{Ro`2OCrC!6tuKeLq%<4*;jK!e2=TnA zcgGT8J$4XQ_<+`^LVE+TuIw-W^I73XAhs7Dyx)L+({*vO%Xt(${I6}wQ%QQbU(QYy zey)v)<;KyxKMPc}jjz5}b%D7(5=fjR`E3vVn|`|}9@jZ*aV`YDHsX(ij%Nqz)ogSd zJn&L)ySV!Y-lUjekUnomxD3oiEo1_e(J)Xl)3P&?Cwr5D3KVh-)FBqhvvLayjk&^8 zin#?4c|=QPtpS}KZQ9DEUwCOLD8sL1LTEZ^KA*n^`|Ed>d#tZ^ zn@aD-eI*aZ?iqj|43y1bnMTUfkQ0yX`m*mO74?a!O#HlOt)`v$kK|$h{B0R~IgaFn zynVs?>2mY2zRrTh@GmIG?FHLUPS2P3s)Ix;Xk6~~`MGgu?$Sd^Ch z$%#1(RtW1V-7;YV%ipAGNH)LiqZIk;<}^BWud6N;YXYFNK`yPRi~PlOT^g(F@^kh^T+KLZR=xCez2pd{K43Kv-em?d zoD2{U3>bf98J2?AI(%E`3s{H6kZ{k}uok^)3d>=3q`(2rqE1c68*YpuH@&5y}$|xtXY038}pbBkM+Y#t&YH)U;?dn9JWeNgOoTlc75g z0}K$|J~d0s14>Q_)pAgsq{?A}m!%^f%!I~VJ zzi8A~EYEu^>Zs!XCdbgi?d{Ikbj5ta;NJ+gkxT>S?$M|)hm(DfZ+X^0=xP|7M3P6M1MOATg-y4-6omvoGep866pRB4$D3v&BNp*OfrI)S6F7oPFs8^t` zFZ^N?aAar+0dyZw*lwT1!>%~&jfcqme*ZJ!nT)!2w(gt;%sImv0-e~X*j!CEN;MHk!I3Z#P4PLf1ck6R4P`KBc6Wc9pUX3%M4APfB3z(4q9 zwL~@ujg5L8K8-4-2fhY#MBk^CEJUZ}q#ZHa@>{=?{CwAYf*T`M0#$EVD=a;)t%l;ca8$O*J~oU4k34 z*?u#_Fh<*OB7G8KE(Uin@q)$~^ahEe2%3W_>th>*@(Z@PlZsi`%)p%Y!ECE0>AYk=qwE=G8_Q}2E#nFnahQe7${Zn^)$ z{kUr)v8~#|LqrSw`_i4z=!&obi9VC42^lM;fuJtM-{y9GzasfU9-y+BUt>8pna0l) zPS}~cy-q+E>haO2-X%-%ibDHjVeg$ucjXmzkRDA-xE-4rq;SU_VgQ=+8+#qAkcGz@ z*Duf&QVw@0lR^w}f(cl3#onT{iT<51Mnb%QI~el#I5_Ccl0-E~s+80hHQ}FbFtm^H z;#VsMI`^!y3~fq?{CLXrL+d1FUTlxdH470xx@|x~4Id(Fusxb4NtLU=6_5p-Q6g^q z6na=e#Pb!Hhem%uvcyy^plae*9$`bOl@UWl7v0_X=Z!X*IRmsARE*w24ZEH5vE2giDaE{AHx zH-K5oLIdI2lsW~!ITDA-vktpB>9KbCXt|^4RGbpGVmD7^>?;k&TpZXY;}{d21%CY0 z+&53GZCwz`JA$n+HF6yHD(W!?Hg14PicVqPRC(b61D_`>i>?{{#FY<# z9Z=5=0@L)vfx1$F8)k_(03@9c4a8Inr?N{cKWs_PM7}x$%xIm6@vTOXahpQQXK(Yz zB<{P`!RUQ__h$t31#a=m=x9c(<511!g9CSYmywh8_x7qEY{Z<+Y^`mQn$YJlP~zSp z6o7+hC<(utD%%gaTpTTH@V>$@Clw2A4NU=Z7^&JEXnN;_@!J8~B+dMm{rLzE35(pa z!XJ-_zY=(o%QZu}@6`gid;4XPkIs3ib}oUAZ!cU!IWt z=)@TCib6$O-N&cc#a4aE>#lz+|6y^xd%^|jcPNhCSlwv_0wIBC9QDjzCCWTPM9@ERXPx&1Mn1}cA*5w1d~dtNG>JH z&}?cdQ96OOoSdw0J=0+x@9t{Z4f>bYO73OIoklKqYd7p_ObYUdKl4>Sf7hIJ zC@8K>Q@3zPS|Q~^NiY;K0t78qjS$4ES-OFk3J7ns_ABop?8>0O(Z5ZfH)on%j+Y@0 zEr03tc@3!F)ppdj@ZDU`TI1xgw*h%Sh!5ixHW%j>5~psaZ|zlz9JCW>Aso}(4tfd+ z^ogOTN);N#an8!u23J|bnbq)EDOmnmcvdm>2)F&j=st4cs0DGuTUBeQb9SpNG;5W+ zf*LvTjbG|1vGBGd3LB=8swOyFr4?&yx{gSRQJz0*Ec9$fJzMK&HU6*01tz(qeFlv?+QOBsbaA0WKrR0Z+{+xR# zGQ1yOUe}Xfk+9B}J-8t-V0;A)zzKl;)@fy60d!v4;}$QguDVNLp~i$5Ia?WZ@>R`6 zBUcHslLE1Mcv>i_baS;2n}Kcn@lID~!iV~RN@TsQUuT)=V>UGM)`OpQH45B^5h)6a znR9AU@8FZBjZy{%PZ$&$bF<=~d75_0j=tYCMgS&N{_dRex%^gT^KTeP1MXp>Ye{X+ zpsXxS12{jf`6?(vk3c*uEk?QIzu)(G)+p&QRa8$*RL&#QAH(_fAOf@`5rEf3am|+! zJDj7R-6#70!`3%M=b{Ab#%{*|F_Ewr$(CZQHiZopwld(fkX zo{tJ`$j#D;Ub6#Z)cDixtl^c(&8J40O45R4YO!-WlZ zO+a$0gY^AOo{mJIeZAkfx!^5WBRnzFF_V&5Fje;F-}kkb&W+z-lGfp7JC2&DwyrRb z)&$|}U^8IdhCvNQ4_#$XQ&mkVd_Rivb+GUfuU3<#l;F?&HmN{T+9S44=ew3YMG2^i z3aA$E!c*-HUH3iPuC4Cp=H=pGOdRBtBYrMNKOu^qaDH$6yBn-#xOE4_Z~yf;)^YMp zVs&!u;cRn#Jc!JgE0WCJ{G9jX-?}TW^e(QX+%G`EUQAXVAvVEK!A(_5Z$VUUf-7Lq9Vkth2M$nS2pZ z;o}A&;%N_a03w9C@w*XD?{&96PAudl@wD74 zgatstU~v$47Z1btQsw<70i#7R(PE@%Afas4_AJdVKE8F3nk?;0(}1~S@?3od5Q)*~Te>4t+Z=@g(W1g#LnL1g9)a>8lXzF3C{{;%+F(CSZq&(W+%JOQLF z`Pi*{0XLsM6u*<2qw@32ro1uW?-&^U^hRIpr*46uwiKt1?*7-mafI;gRfuekaV zvvf~s6sXUX4H=f+%$s#A)1^E6%>V~O7gY5Lv4*)?d!o7a=&+E<@9uVyMG;T(OYPPZ zJNdu*MMemE`>SD;$7ML9$!kt0i@n{Kqdu=JaIn0%%>+178c`e$gKqoB5b~|Z0@e=3 zcK4PhKhcS!j3V?+Bw1s3gH#@_NRgQtNQ5pyS>^1_{cWXXQyjkJgd8ws0crxH@E0h{y+Pmib37L5lw(@6R_s91sk zgShxiZV9-cLhV`}5C;di+s_S&oDF7pE-_CF;A9Hl5?-9 z*)zsD<^QF<{{n4T()Ijb2rvr~Q&KV^X%gBcI@RH!^&LasSKAd3=!YOMP>~W0&;Rv= ztx4%}4hxi-<3FwL|Der?X_}zG6#w11+WymbLLz}ObN;6UB~PnI1!n*6{6AVyUI5$w z(tx`v8%U}sVF|eFY%LaxGeCewVAMPgCr4ZKlULA z5Q5gE;5yjKl#1yepI7*Yrd1MR|k>WJ>CxX?+#ReC|MZyUSCx^2D*I}9p6HTlSqxa?gMfpQR z{_RLA`dWqvFgESWIK9EegYp&`5WMS`tc%+*|8gFIItppN{+gTnX5|nbf0(u6t8bti zA9QS8^UlL{EtkLLTaKRTS$npf`D`*jlZsOI)AeE#==RW&v6*j~c=*17lBNCV z1`g@aD%sb?@@DUyWL)_BVY~VHE!yab_sH?PU$V@8O%@)YDwM7IsBFyVtC_C4Je_(;VL#g(?R+(AU^Aej{%c-DT~GQ6 z?K3(Lb;^n=q6gyX}lLT&Asi~$}|#2+b%!wqP>%-O@on_GKppV zqW$4X(V)tJF?Ax1%t_V$fJod4cKd%+Hs^m*WionZ*8iUiu{OjC5Cj79fdESQzg{FM z{#VV>gpx5XbToYr z2Kzt^+oaFy;}I?T!<*VIhg8^HF!<$vFyv{$EdOr5O%?S}3JXfVOFj*WL}JXu9E~N` zEyqXvk2*1u?jM@z753q6%jgoV<}GDh&R!~5pXdcbEBIJYm9?DJY;(rX{{rW+10@Aiu1n9Qc=ftiLaPjr;nU*?68z^W*Cs?vz!cZ)cXwqF`3MABsiD5Kj z93v4~N;8zE@QvZGVLszO4gT-`@9~<#bmTVByvE!Oftpg)6o6Hfs|fgEabwhm3Mep`LX+qZZ&JWRJ%YM)3kS)(WeSljvC_+bl;}y_51^j;D)E^ zY6re~B?Bg4=n#>|RCRRuuiq^1c9wjO?VUJmV?c>x)_x!Zztu@K(pC%uUxT+iK6|4@ z&GkVbV?#R1CIdPVc&tmIEPQL5feG7@ACAMs8=| z72s!2lvO8rOn$S~XE?uakV}HiD+Pk+6uBvuO~(OX!P$XH+HTW zsD}I(SjPHF$k9=6XGQiYJ3HEEb@3d30=vwy(3$al-q-ku4UKUsj2jxJTy_!YTR!py zgwB{_-xg94k|(B>pgmfYpY=Xi8o;3st2QD_y{y(i6+suo9r^5%o(|HwC7s#RmXkSX z=*@>YH(I+6+7oA92yd~gGECw;0FR3f(fsQeCFGKiYwJsQYF;$Z_)S(WtzJgE(ogYT zBx-Lqbv)!7b6rGW(|ml61YEW95URQ_Q>KfNH-I;Z|UXt>w=3bUlz?5r8kFgM$hCbBOZh zFY*M|HTIm355YE)&l(=HS}useFv4-*#M_-bP-L*;aYFhiCDi{_4V)4tb4CL~8I(cw zqGla0wb0BXF`e27VF?wP{H*VFQ(w7;@Fl!S_%ENvvp=J;Wam;qRIdUV13@mT%9 zM#bFR9Jb2Yat{a`PIVX}c#<1%#-~^?0qFnGCVtQV;A+PD0a9&Ww=M5r@9XQxyWUC& zsfrj4?E5}GT56^Q)#_x;x?HXTJEm$~3@p0c3>-%0M-o5NkA!f+5aZDKe6mHxf@Aqg z$BNG6721J&O!Bqg_ug|F|8U}eb!8Q+hSpwi*!4XQLteWI+GQ87|NjbcL_Cw%&a z>hC7|r8Z=k1f(k8y@d4(M^fP8F;V@cUl1FAKtY)4NUOpmZmJza92vL3qp^P2?fX0O zr85d5%K+0IWS=k#)2@wWFIky{$Ah32rpXZ5tcJ1t_eM=a0Jd{KZauQ6vq0khf@q zgV(>uL*>;w^6>@QlvX}fo1FZqh=IfTyl@xWsH|2^#gP<5msJTkKF43E!nOiBXy7fg z!ptg^35zd9ke3dmcBK0wH9DAlh*!hFi<*qloc$5XZM%-2HI?dR&EK}vJO5`8-b36Y z?8fYx1K_T|J)|s?X63>o2i(**t*Fv8woiDM)tOaNDL&J~tc7)WD)1Xlm4q*xZV?-Y zhU0uD$4uytG2R~WE#HV@Hb!10>kDsi`H}=y7|C5qv=LY?SW$b!W@Em|TTpq^vP6(L z#f_~ll@Lj2F$lTdgJaw4(A?RKGjKUR$>B7yg zH}1>IVn}Sz>Ub2v>`5bzlv~HWx|4y#@N``0_fzn%g6z4@AZ-*4^1Eo?LECGnAy~HG z0OMpjsAVEefgg`P#JP~w)KiBR*4|P@pMK-C+qR0ZhORS1WaBhXVO`dNNe6Ys$(K}6 z0gx?vN216)(K=NE>&HTCl~Wknb4ki3gn2MI?>}93MvtO^%IK+}ovN=98WRjgIAOq_ z2VxDJ$Lf|oZ*J(cd_H$F4d0*_yBeEn<--48FWNsoEhJtj#iWFuv?5ihc5&r=wfw9zD$aA2J+^wn*Jjh@R<|yJzYz5cd47!pvDMbO0sna+tR*! z-Uw~)6-Km?C`?m-1L&-aVI!f@=_KW@Ogf#SoDPsD@yt8 zPcpWR<#;IP^s*?z#EkOEni|_jRrqvov39}NM=#B!~C8L=|b0BI@kcG$es z{H$Mth^A!03m%|+79;C9pcp3jU)n-PK9$aczB%uqLALfF*6^vx5ZkB zlJtEQ9)6>W?YjSq(TmR*W&EsGJ~vniy5}{9b6xZ}6+jDFBX~9Hwhdr4X`6EOh5DkE z@(mjM7ok}B&(>3sa!;4&w}<4iYPYXkn*IB0(YIzJ=C{-g{#U({39y+-xL4I{}VKXDW4$hhh#w*dTTbz7C?Xf&PA3 z>JyGne+5K-1)t8!7!Z5&=FDJ1?Oe!2%VgnvVI;yFcnXmOJaB( zcTd9yKR0l@4!^OFZ9)DCB`4IBz=~x+H+1rTMs4#OK3;0j(+XI)%oD1pjeS!9;y_2AK58S1E>dh;@P9oo(+_ z#fSYn6xTmB<3h`);tYmY#jEcc&h5mt*pgb~8j{t0-g_|F=CBsLf%6%Xp2wL8OJrUN zqpkT5L<_XVsow3!2CE+|F$L4;#5F`dkcs~xf@^-9| zUzrUzcE<<@&jU8B^zvgtw|n671YUJh4&GbLgi>J0ENVxWq(}(!V=TKpqsYa`+t+|H zF#|#BpKP0$DFJrc%I))twHq%Aq89Vq>QGf9JsMOt2cRfX9GQ&0u;{>41oG+QWJ8nW zoJrd-rtdBWgTISN{LP_K7P7^A5^Oi78f2b=Ek@i8G65eaGBl`AxO`=S`-121;M*b3C4ps~oGz!0`zT=g?m!OQ@}-4)VU$hhxj=RzmJa(0#kLkIEfsyp1M3~Yk*nr4%M!X33 zuRW;0PM}cb4|7?i1YgR}`z2W1Zj(49R)ImJB!NNJBse%$Rye`L6miS285SL@ciue|Efe#*{YkG7u@bUk5| zAm0xLjcG7`Iejyn-~{ttO>vOl34I&kWHMU?2B_ZikPx+{0)Yg!`u>;qmb_KlW7`Z} zI&+7TeyuithlTl|4Vh_@)rW+85G4FTj&P#Gmh?jc}UPZB1+8!wN*e`ip?9kfgg zgQ{}otkyjIA<{RgzDhYh-5U)>l#_B>-h5JuLU8C6EelbH&f_b4KAl92isnstNV%H> zMP%Bi@U%4f#&hdBc;o&J;GAJcof zFq-eL%PRy9^!697tJxn@*Srx3*aj$!D=0oGG2#$k!EL5#LVe@%JMTEn;KQh6>g8uy zZ4u-HYq5g15RrBW?$i3>{4SR{Wa3az0I7K?J9SQW?@r<0{;e-rvx3}PjPI0eWvG<l1Fg;;y)X}?)_5o^{CC* zk)0kVVF)qhfK@AcI@M=h(IojjBrs3qW)^Bgx!pSkxej?FpTv3<$dE#{v3_)a<@D)x z^dwO-w(o_I>^)@58~pE(-t;DvsyPIe9aqr~agse6%cS|FZNgaA1qUEy;!teJkg22F zNGNACXWxh6@r>2ETlF{s)JGm+)3{6T;K8E_5#ic(}lw>pK=& zV;VZm3Ij~5FU^iXN*S>2yG=AA(x+h4s|9${7O?H5_Md%Nv6xrTfFm(|!h)$oF5aId zZ|u6V>r(;0UDbPkM(}li?Vv_YU1xk)8)I`w`3zO*+ShkTyrQu(+ng1jl~uKeaW)Ea z`>YsbKg~>ra-~Tslv*KMh{V%`h?Tr+t@c8U)55+!>}rk!!5%>82M8;0FJ>B3YLHC9#E)p2#MvI;|S(A)KWOHV+ab`C;dH7`FQ zw=lVDA=i=r>%Y-p%473Am8Ca&cp!NP3WfkiW`r*TUA-zy!IGCux$ow%+ETL{9g}wY zpASp^je>7dl{LS&w&j^4hZD!fT%dCN?#2J4LDQv_Wx(YtBUpOpB50y{M@9{cTB1o; z0thmhAYkd~;`wSSV3L-oX-c%A?>Bd;uKTUYCympgF94xW^FUy5cTLJfXz469z52jC zky_1dZ|+jE@~M^K)JtaQ<_%PVeFodgYxh#476Ej}5)Vt@o<7~_bBAMD#}h&9PG+%| zK^SrYe4+B{Wo5MeU0j%11>zBn<773h=&7)a^^)Y!FXQtN&^`xNr7ZQ~Vn@u0!{*jY zk?Dog-GFadjGhp?Gqp7QTa@A-eX`{r6^3l<)9Oh;Tz>0M?KLMel_Ki!{s2V=p*78q ziA4#`i0R?6zB^x-Lc9gb%7)f+FKm75+^`x2D!p7)#m8Ayz5;QTLBNK-4quvvBpZ)h z>}`xSZ{M`+6NBkOt$q=iR+$Wqabyd(SYRaVJAkgap7YCq0cK_?ppTNljh1vygl zJ}I2`K=edhr(vOBPbFa>Q*v~)*}X}e5LcGAfQKGIB!N71MFmYdc?A*v`|_qbH0(~SCf{j#ePmDq!LI-hxR**?2k+u372XX zJs|jwa`~IpE`f^Wi{awahY!hD#V?Z9>N1Mz_)}hr*j#PgT#=?%a$Mf3NTs?}Xx12K zQkR8cH2FjyL;g;oTYhVGY5!~~G-3kdz&bzR`KcDj(|W~V9vy{@S<^>>*?AibZg zg-tn4TUGc9_toGZoDaKFVii@S%HqU?w+Oqx^2^dtr+SQ+!Ec5v;ZX0JpiQ(_&Tj!6 zg&cz=ZA^qZ73yLNoxXq7J&ucTA`MlVmq`Xq_{Hy{Yi zo_r5V@%T8b@>?B)J7FB!m#$;miMeTEIKLsQ_nTn(i6L8Ug#Yq@NKn3=`&L_4%Ig(B>PnJz7(im}An zMEYbQ0a|GG=1*B|YmR^c=)99(1mM`pRzkcYe^%ULUjiyPjF9SdPwcfc=vHV#iD5l^ zAgDO}h@Q+7y!4w|I-mgvz@WC@F(~-K-Bkz%YE> z%uyXUYifigvc^-_Uoq?>M2B!+m#GNoo z_9}w%II;73MR{dH^d7WCT3NOc{AZyn@NjvfH%{PFfpM6uRXTOpav4X`df5t#aTr3X zSoN+6GOYI6T0T(&#Jz=uEcUfduDraKVaI);VP_QraW_3 zjCedCbBsp+DI1r130^2H-_4<=W(p+oM$onhkMtxX*MVP0fhH++Y9t2mz0V-_k!-F5+ zX|v-MzdqJ4OK6Dh0sw?SWRU&N5u&ui3zYqWHo5-JCDP07{lgk%#X#MqfHJPV_`*}E zA$j?3WI@x7uSp9OGK(d~04*3Xw409^_=Kym9Kx$nci$KsoG+bPHM?@@tiG0wBL0QU z6y$;Yzi2-$A||5$3GCzJV-&Yc;-|q$Lcc`9Wa41#{kGfu9pyCG<2NFLmIMacb%w@C znlDC6^9Kdy1F&-aFQ1jKCafmvT5B#;2JnbK+yX}stI$KhWYHh_xK{PyL!GL?NE}b9 z1)|9>dKi!aGF~ttK~+&fMKJJ$FrGqntCn)x6)&A0ug%YM8Cx0K8=TGy_d5h-9s4={ zkKSuC@7G_6uL&?A$ouBTP z9Nkz1q5MDTM-l)j%)5 zVQpL0ZuOgs3iUDT7Arkr;b{Px{ax_zi~fS+RnJ-i`@=479%JNN>+Mta$Lyfs+=sK- zJ0slvo3x~qVqH|MN|-h3APL8)cTe<1lmVKjV=^s!G>*Kd((bayCE@bbvZ)o!3j}-2 zW09FsQ-$ZUj}>rBxV9{P0Z0WAO)yN!U^#noY-B!%V#2bx6)L*Oh%&%Y6(&WxWCJOD zVk+pdKG0T13^ko|^7hTU$slRQAqy^xx7EakaU#otQd{J%gppO|+U7d&hUaGGRr|~Q zC*@}jVIRVUE0~9k`x&lUxt%%_&lX<rbZ_JG2kI3GfvqZG7Ee*# zR!rw3#7tGYBvA77U`wN645fPg4{%Lpfl#JL;>M*d`Ncpxd@T zM9U*Mat04pzGCe*oW3T7@2U&A=3j<@+}&OX0+a_kll1Gj=3R}WkTtG65crXMUc-Il zZPf5dQj8+Sq#+tyz!TGSsSYA+N*twcFeKW8V2VMHi_FW+Fs}#79;*td>YRwIWw8TJ zsn5f{H}Kbh-U&db3M2ZU0Wo<%x6^trt12YuJ(dO32=jXO=)(aeb>T}4%}bRFB@~23 zEz(YXkE(-h@DSn5T#(cOn9{+>q?i(^E?9%VZ;13;U6g$6$suy!--Z+Xl2-U&NG>Hw zQ(L#q-mVkxtJUl5YY8Ivy~igy6o?ykwNOCA!FOi)N(LYy8}R9u@AyqNt*?NlDaLXB zQQ$M|P%GeP1hYGvyVuxr0K#dz9(ou2Bsbj5X0I`joRgWj9T^(wR95>K57 z%j1WQ$G}x~Q5!7l98XOoBrhW1aS`B!8RDZZpXRC?D2(LVu zD{Ge5&aQ^bcujYyyDAm*i;qv#90P5KXE22ZnZ}zL4`P=D4&AoXAnlZzGf;o`DG9xQ z4%$EXP466R4S~g!i#R+zsFHR1sBr!w5K4mm`T2UD`5UGjj2%9ya(D368w~tgcGizZ zSQbze4F>vxglAjKt=!h=`ZG~MkPb8CH!lS4(Y}` zf7euaiO(C~5U(&dEia`M!cn}8S6gRsfWAn1Y?DD%BbhpYDYzv$CS?K2tulw#0ij(Fw`GMTv$VE4-vijg?YtrujX;KnVwghj>oAL~S55wmYNXw# zj%g5|=9g59j27ZV4snj^iT_)X5B!!O3lj;Wu)kzN`jW6+EY*@j8!{hT!`Z7IaP#ji zuI0%*(;nY@`sdRE$BZ@vEowt^WF`H{3Jm4#q@0R<%3^xr^o%aC?~b#`gFEa$^dAs6 zX#GHg70^>~JigRD%PK6pQ?f2>$4Rq8+HV#59;v}O*gj@25DUQDf@+NuA*i$0-8+Qi zB_ygBLewqCO1(_vA>;h3rag4&5+j5;*u>7b%bHQ2CqrV||GlY?0$9l1Rf3 z`0Gs8x3ZtcW`MqY0E=_q=lk$^a1EGhihH~+Ocw#Z%Wu%VwlbYX7lvWYdaa0jdPBQD z)(T61S22%S!E1Nl?qwLom)fJn+to?XFm7c%#c6t`X$8pYYFWw2X?*|_NW`i@6m6h- zy#Ay^pBE)jE=V8}Z3mXUOXt71YuaCdZPNsG%5Vcl$_CyI#8l#A-!XRTlZcU?uz}Ihn5JS^dd)qxifk>-D|wUy7qY1*?V}A6OU z^0N>(lWZADT-jFOCnz}=(@aYL`mi z2>Gd0u#rdgbh{t(^nbIZw+1XaT^Faj!OZx4ww+lAxa2m&q=s0rLlv6+MGrjP7|R}9 zWFk2COdx|E*BufUeZD^Hvb&7y0*=&e<9GAs*1_;O8=SWlwVHrlz6a)Cp(%+K%nsVM z!ZS8lxu?gy%n}l8!9BW$o{J?|tTt$mHfnYIq+6-`Ja6k5CVN|q>jk4MPyJRFu_vRQrj%A#B; z3i_BCj*>h^-!XvRJ$abi`gO^hclrb~BzH%X$n$xab$PZ$pos=p2#XPQpa%Ii;=%&k@8!uBzdhQ&>47};=5Bd{ z$gclkr6qv(iqrg*HPZKC)SNAyb_1EdO^r6%V08g^>cvjwcdR6>ooprN>tt)| zE5<4mKpu#>Nx^K}NUN~FiHdsxu^>{P;j~tkJq94XJhqMkiS^63;$8kY%Bh9A)*cx< zBQ*hc2f8UoG1RY1{hKAb#qzO_^ieV59Hs8)u^rtobV{J5mq68A$CnA(_zqcIT_fAL zm86f~rQJf~c6x8=vF&$1e)^U%A1lg0aDfWOmqul^+FRJ&J(%-dq4JnQ=vPI_>E}c_ z-UWbypnZ8sh(Xb~+jaqEv8$(E1XHBlO2l;ud%xct53DG0yMj4O4X>QFSNbTEQwrdH zcWL5oo15kBF|*?=Om^sHQ`e|Z-3snOB4~62O#fpm&{`|*YZ<9k`n^~cqcN~gKF9EG zq7T~3$%<-y-k`W@sbNCAso2*Nk;~wFTn2DA=T(6+f{{YM=tzEVWBjclIYvSsr=T%R zHls2_GsCi>gD5_Hyl#B};j$<%z&{)CUjCj=Ex02SKUU8f4(l!CAH zHa>G&r?%bgpx|n)O-Zc-DVy^qZlNc;G;#T9a>q!&VRwqip1rO$=4+SHW>f`@h+T`h ziWO6;o3z7`(}0$UtgO;ez4p8`HPw?$ zXP`K5p}g}?G+#lR?)*4f3uFf!AZiD)lPi1z--q>Y^Y6m(XqDZBcNA5CpU`@0Jzl?H z^<6MSh$|d9I@^>dXfOeQen!zAlA<#W{YGK&&pQuTN6D8FmfP3zIWySUdjb9c@>?s4 z6S~~3QtxDM=ziOznu3Rpby(w>wNfVQxffkBZ_3_h{-`A9@?o+%f!1la$nN;wb)FGWa zRfl4`*~00rRcK#eTNe9Z^#J&d0?m`7G-|#(5F`7ZfKg8%R&I-oJ)O|YCqAFI#T5GJ zPrE}z_PqS9viFK&kM9mTDIDTStKue(MS5kD$Y^GUNwl#K&GFPnZ4nOP(QR9h)**~( z;h67kNfS!Y(uosVxao7p_^}%ru@YUahLS=}e`=x$cg$l<{R6bxRseg6)J`@P@4i)* z;gOZ~?Z^yT5i5lACir+`uB6zDWwI8n;a)D#H6!>GVN#;xl~g@609DH+@RVTbFjVh> z@pn#a{6mjoPdC1=CbMdmaaV`PKd%|?+bgw)uS4szHh(%>!`zeI9ss^6lY6+mG$w})X%jx3J0+B z2kFh-*QQYn;O9>Xxbgqhb zMflk+_yp720eHp&+ONDGfNwQrq$N8PTM;_sD1IJ-F=uv|9du!ql^t9hZ+4|WyINf- zOD{3b>=y6gjew~Vn!7yOG2Sr6dn{h@==ayFUKEUW`mBGi#jYhc1x};BeR-ecN&|nl z{vBM=O9wGi_~y{mFj*Qv+=X)b&G|eSEv>nxeBO|E%MN~G%}X8Pi6fLyT@tRIc^&1j z$`p%-Tol-=C91LN?^LH0KXDvI^74a>L}^`{qSJ5EV9Du0R_DpqP*_-Cgy=eeHqP$FX1ROl?nBbJGK#F*)1VH1{{`S)p< zu-s{*$U#{OpHi*S4!4X{>@s$qBN$}>8qN@l?L1G)L85gvOZs2pRl^pIKO$*{npU0^ z?S>gE76ns<28QzyvXam-EU41h7PG;j9*8RN6yDFgG2U6wjE)MeCIseuNxF`@=dv*1 zFVjPWi*tV|*vF7G9Adur(@hRoxh?6dOTEJnr%e~3QOq3+4$uk?tH*GF1?O!6kE*1Z=6Fz2v~lcT%-M<;|_4l{UBoviJ#zr3{m1zuKYQv z=s;!p#H(?HGAJbB-0om7_+1p3&~iyyy224;RC8p7{TnI<{~bj?kNJ#ja9BRA$%uK7 zamVRL7}@>Ma`;{3{9bV1bgK&3?h(th$`qA@Uqg9nTcdx7jc>m`W~Ikp5lQLqfM;kbePy3T#9 z$|$MxI5nJ#A+l*QOrrUOqS(e|xed{@sKbdQMPjx!L_nZ)IMFD0dHh2*RH^GYkuH(^ zMiAr>W!@yAep(WX1ibM^)q!OLm3o~$#S&gi1Wzu;6v|VslOYP=7CF^JNHkU>bsJX0 z)U=z#rxG1Zq9v3I6@%Z0>-(>otijod#rxF8(t+o{3cNpExw&D5?Mp_cO)lKeB*eJ_?M)^EK9>0wa0TgPVM#1p;tmT&mIviC_ z)q1Bjl19D-lAQGEzLHL=4Sc3G(w-W#8SA_#HJ;)=8vF7A8z0pQk5;Y*no(z*8%X5+ z(S_HTX-dIv6N(~S1i|hx-$ei|I1(JsKP%tkI<2I!dR7+YlIwFYVb@|tZpEQ2g! zuTM%%y*NoHKrr0B9rW2+T~){Wl8y zA-|xWdz*1@2(7kD8}Og7aoSdeJ^@vh&!3*#$7bBW+5DUtBoTCed@cH=X<)O?=2JrB6Muk zh_qcQ?lAcr88@kL#H{NH*-LTIWSN+j++ZaE_`T8|$+J|OE53bDKYE4=Q#<%>)wM?r z;p5QkB9CJ>Ld%YFz0*jGB zvlG(VqDJ1k5>8{7&mh9h*;||Brvhrmba~7gO04nwJAC}TmUu#gK7is@XVUGWrI;K6 zUGk+On_U48_?N{5`~G`>PGA|8t2#=rYxmlG#n&k_+EqJA13%u!`JZ zH|>~IY`KrVu5T1aD24w=)q4K&+?@2g2g^fo#+Q=v2_x1gSQ&)XJMA!!{`6nCWoT~* zrFo0PqX`82$VDt7be|Iu^3CHDI8;CYcHM|5KKk9ssv1ZZ+E_=21wRlnA}K9y(SWW{ zc@bki<*bQwsh9TwtD&=ff6a_mi&aoa`_T1}JFQYWqDrW?aPYYYa$wWbeYw=LDK39&#b zAbS4&s?KWQ?Dm7`+F62=v^_qUt*MaCAcn5#aX>H&2>Fv$@9HqFf3Gq6;U!By7uW@a z>D1WgmieF&Y(B+Wa@U;N4DU|?y0)|(e?SBUlfEH5JW)jTuIz!fkb~=hRGWc5VO#SK zG;p9h8$tCNrO9%mXsX_cwH6uym(AiXxDJd=jz;u!@=W(p~8yWxm!4mH}*XKdbfTIJ+ zCtcmgQtF4aGQaalQ)&W0zu`DqaWTuPv10lOGb9>igbv%u0mm|tyc(`9TZ`o>%d9$M ze4bPN^r_T z{=FAz?~ zH0Slku%XGk$2&>h3}sxD0_o$nLxL6~O+i_ek1|G8(pl2ex2?GSLlfeBllDm(|7Q-( z&!Ca(qvflkA8S|lzvLf3lJxy)reE(mOpPMA9J$Hwv37p3cj0aOXua%ZI9Odw+w3;8@JUU=R{oABIsqq0)|V*a-bms8)6?^~eZ4R$}D11O=hS zjGPf!==CFuJkwl`wHjIawh#HGjSN4|h3m1ABqEbmj}6SgWaCH9@l1P_8EZ1?vU=np z$~hJ!J2rBl)JBvwK6bmX-s_Q*;Y&N}MNSheFu;jSkv(x$@PCe0an46h(6mSPkdz3owKbJ_Jn=J#{y@x?N0GH2wAGb(vp3 zTV57nr*t)6m#fbwk7mV1-W&eBn&qqc^6KQ-jJ~rdKlh;N=4O#!)9#1S`33UN^7V8z zzrkK4d?QSc_OmycaBTP{e34uqw>I|HD~6BOQpu5-_!?IImT`v-!p)E2 zqko_<=h4TjH}e^`I-1!a>M?DO`Z#al`0MBkY5LF?oEQ(EVPi3$K3ZNa@{A3iE+$v& z%s}pE9Qht#E3z!s`2)83PqW5<4=dkjL(`2P&3HOr^AxvPD&FF}lGPldwfL*n;{4w$P{O*nfd7_OE11Cw>WAv}m$L9l@3^ z`Ny)w-(`zGo-OC+FW#B~HJV{`7`%)6NyUr>^);nslL;5XG`RDri#2v6@ENbe){#NcYlxH*49KA?|~`tbKR6F`fp*1ubASbYGF#Bs{z9X z-Aku8q~Tx1nhqdS(x@hB%n_t%mwq&7^j*$~<2m!@?VHnQ8)KfAFz240MP_%CYYyAw zS|=0Ea9eQ(y$NS<*I8W@ID@014V=L-q5Db1_dJQZ$M#8qddks>9FqmvT-8GC$lCFNg!Qfh}Vp^Iy7fZZ`0;8x+s zawYCtnq1jzsQwF8c2iiB(4-$wRC#b^FIZA#W-m!ZTRdepVKz21Wj17FIX5*oVmLWA zFf=tdW-vEpW->W2H8wsxWj0|pHZx^5WMnxvH8)~7IW{mfH8^H4H)UorIWRRgm+oHy z9s@BrG?x!x0VIDkG&Mdx3UhRFWnpa!c-l47$y3j99LMq3JA_Kveq^bnY>{jc5q?Pv zMYa|~LW?9Rm8C2R$ui?&oE*6G7r1nZa~CtN#?j!y<=6N7oOhSUJm>YfzCV%_i^WN) zx`J(Z8WS-Ad$9*^VISVb+jtKL@FCvEVI0Dz_!viV#H4=|iI!PXruP|BLWQ^CSyQCM zmpD9U%6R3=G(2z0$@678UNGg4`!WNY@FhMsMc?>qJYF(Y{qV*#$lbj-jNSb_C; z2#?|sJdBlCg~zcPk6{g-!V`EB>#!DEu>l+LBDR=Xqrt_h?R{u_B(x(rw6iv}Yc#aG zCA8;5Xzw4tnVY8m3Ga5(V1ajk&{Ow()inIt`%X>Jzq~t4ZyUV_gZ}J&&GhlB_XE?X zT<=cPc+C5e=}Uw6b?;^l$GQrhh-ZUzq++{mpK(#If+_rWHz) Zn3-Q=msw%~91J%zFflm_B_%~qMhY!-KQ#aV diff --git a/lecture28_31/notes_28.py b/lecture28_31/notes_28.py index d4197a3..238a0be 100644 --- a/lecture28_31/notes_28.py +++ b/lecture28_31/notes_28.py @@ -397,4 +397,241 @@ print(f'validation, acc: {accuracy:.3f}, loss: {loss:.3f}') # ## Data Leakage # While K-Fold is good for getting hyper-parameters with limited data, it can have data leakage if not correctly setup. For example, with timeseries data, it may get access to future information and train off of that. +# %% [markdown] +# # L1/L2 Regularization +# ## How it Works +# When a network is overfitting the data, it typically has larger weights and biases. By punishing the neural network for larger weights and biases, we can try to reduce the chances of overfitting. +# +# We add the L1 or L2 loss to the data loss. L1 is the summation of the absolute value of all the weights. L2 is the summation of the weights squared. L2 is typically preferred due to the smoother gradient and still allowing small weights and biases. +# +# ## Backward Pass +# ### L1 +# $\frac{\delta L}{\delta w} = \lambda \text{ if } w \gt 0, \text{ else } -\lambda$ +# +# ### L2 +# $\frac{\delta L}{\delta w} = 2\lambda w$ + +# %% +import numpy as np + +class Layer_Dense: + def __init__(self, n_inputs, n_neurons, + weight_regularizer_l1=0, weight_regularizer_l2=0, + bias_regularizer_l1=0, bias_regularizer_l2=0): + # Initialize the weights and biases + self.weights = 0.01 * np.random.randn(n_inputs, n_neurons) + self.biases = np.zeros((1, n_neurons)) + # Set the regularization strength + self.weight_regularizer_l1 = weight_regularizer_l1 + self.weight_regularizer_l2 = weight_regularizer_l2 + self.bias_regularizer_l1 = bias_regularizer_l1 + self.bias_regularizer_l2 = bias_regularizer_l2 + + def forward(self, inputs): + # Calculate the output values from inputs, weights, and biases + self.inputs = inputs + self.output = np.dot(inputs, self.weights) + self.biases # Weights are already transposed + + def backward(self, dvalues): + '''Calculated the gradient of the loss with respect to the weights and biases of this layer. + dvalues is equiavelent to a transposed dl_dZ. It is the gradient + of the loss with respect to the outputs of this layer.''' + # Gradients based on parameters + self.dweights = np.dot(self.inputs.T, dvalues) + self.dbiases = np.sum(dvalues, axis=0, keepdims=True) + self.dinputs = np.dot(dvalues, self.weights.T) + + # Now we look at the gradients on regularization + # L1 + if self.weight_regularizer_l1 > 0: + dL1 = np.ones_like(self.weights) + dL1[self.weights < 0] = -1 + self.dweights += self.weight_regularizer_l1 * dL1 + if self.bias_regularizer_l1 > 0: + dL1 = np.ones_like(self.biases) + dL1[self.biases < 0] = -1 + self.dbiases += self.bias_regularizer_l1 * dL1 + + # L2 + if self.weight_regularizer_l2 > 0: + self.dweights += 2 * self.weight_regularizer_l2 * self.weights + if self.bias_regularizer_l2 > 0: + self.dbiases += 2 * self.bias_regularizer_l2 * self.biases + +# Base class for Loss functions +class Loss: + '''Calculates the data and regularization losses given + model output and ground truth values''' + def regularization_loss(self, layer): + regularization_loss = 0 + + # L1 regularization + if layer.weight_regularizer_l1 > 0: + regularization_loss += layer.weight_regularizer_l1 * np.sum(np.abs(layer.weights)) + if layer.bias_regularizer_l1 > 0: + regularization_loss += layer.bias_regularizer_l1 * np.sum(np.abs(layer.biases)) + + # L2 regularization + if layer.weight_regularizer_l2 > 0: + regularization_loss += layer.weight_regularizer_l1 * np.sum(layer.weights * layer.weights) + if layer.bias_regularizer_l2 > 0: + regularization_loss += layer.bias_regularizer_l1 * np.sum(layer.biases * layer.biases) + + return regularization_loss + + def calculate(self, output, y): + sample_losses = self.forward(output, y) + data_loss = np.average(sample_losses) + return data_loss + +class Loss_CategoricalCrossEntropy(Loss): + def forward(self, y_pred, y_true): + '''y_pred is the neural network output + y_true is the ideal output of the neural network''' + samples = len(y_pred) + # Bound the predicted values + y_pred_clipped = np.clip(y_pred, 1e-7, 1-1e-7) + + if len(y_true.shape) == 1: # Categorically labeled + correct_confidences = y_pred_clipped[range(samples), y_true] + elif len(y_true.shape) == 2: # One hot encoded + correct_confidences = np.sum(y_pred_clipped*y_true, axis=1) + + # Calculate the losses + negative_log_likelihoods = -np.log(correct_confidences) + return negative_log_likelihoods + + def backward(self, dvalues, y_true): + samples = len(dvalues) + + # Number of lables in each sample + labels = len(dvalues[0]) + + # if the labels are sparse, turn them into a one-hot vector + if len(y_true.shape) == 1: + y_true = np.eye(labels)[y_true] + + # Calculate the gradient then normalize + self.dinputs = -y_true / dvalues + self.dinputs = self.dinputs / samples + +class Activation_Softmax_Loss_CategoricalCrossentropy(): + def __init__(self): + self.activation = Activation_Softmax() + self.loss = Loss_CategoricalCrossEntropy() + + def forward(self, inputs, y_true): + self.activation.forward(inputs) + self.output = self.activation.output + return self.loss.calculate(self.output, y_true) + + def backward(self, dvalues, y_true): + samples = len(dvalues) + + # if the samples are one-hot encoded, turn them into discrete values + if len(y_true.shape) == 2: + y_true = np.argmax(y_true, axis=1) + + # Copy so we can safely modify + self.dinputs = dvalues.copy() + + # Calculate and normalize gradient + self.dinputs[range(samples), y_true] -= 1 + self.dinputs = self.dinputs / samples + +# %% [markdown] +# ## Testing Regularization + +# %% +# Create dataset +X, y = spiral_data(samples=100, classes=3) + +# Create Dense layer with 2 input features and 64 output values +dense1 = Layer_Dense(2, 64, weight_regularizer_l2=5e-4, bias_regularizer_l2=5e-4) + +# Create ReLU activation (to be used with Dense layer) +activation1 = Activation_ReLU() + +# Create second Dense layer with 64 input features (as we take output +# of previous layer here) and 3 output values (output values) +dense2 = Layer_Dense(64, 3) + +# Create Softmax classifier's combined loss and activation +loss_activation = Activation_Softmax_Loss_CategoricalCrossentropy() + +# Create optimizer +optimizer = Optimizer_Adam(learning_rate=0.02, decay=1e-7) + +# Train in loop +for epoch in range(10001): + # Perform a forward pass of our training data through this layer + dense1.forward(X) + + # Perform a forward pass through activation function + # takes the output of first dense layer here + activation1.forward(dense1.output) + + # Perform a forward pass through second Dense layer + # takes outputs of activation function of first layer as inputs + dense2.forward(activation1.output) + + # Perform a forward pass through the activation/loss function + # takes the output of second dense layer here and returns loss + data_loss = loss_activation.forward(dense2.output, y) + + regularization_loss = ( + loss_activation.loss.regularization_loss(dense1) + + loss_activation.loss.regularization_loss(dense2) + ) + + loss = data_loss + regularization_loss + + # Calculate accuracy from output of activation2 and targets + # calculate values along first axis + predictions = np.argmax(loss_activation.output, axis=1) + if len(y.shape) == 2: + y = np.argmax(y, axis=1) + accuracy = np.mean(predictions == y) + + # Backward pass + loss_activation.backward(loss_activation.output, y) + dense2.backward(loss_activation.dinputs) + activation1.backward(dense2.dinputs) + dense1.backward(activation1.dinputs) + + # Update weights and biases + optimizer.pre_update_params() + optimizer.update_params(dense1) + optimizer.update_params(dense2) + optimizer.post_update_params() + +# After Training +print(f'epoch: {epoch}, ' + + f'acc: {accuracy:.3f}, ' + + f'loss: {loss:.3f}, ' + + f'lr: {optimizer.current_learning_rate}') + + +# With the weights and biases now optimized based on the training data, lets validate it +# Create test dataset +X_test, y_test = spiral_data(samples=100, classes=3) +# Perform a forward pass of our testing data through this layer +dense1.forward(X_test) +# Perform a forward pass through activation function +# takes the output of first dense layer here +activation1.forward(dense1.output) +# Perform a forward pass through second Dense layer +# takes outputs of activation function of first layer as inputs +dense2.forward(activation1.output) +# Perform a forward pass through the activation/loss function +# takes the output of second dense layer here and returns loss +loss = loss_activation.forward(dense2.output, y_test) +# Calculate accuracy from output of activation2 and targets +# calculate values along first axis +predictions = np.argmax(loss_activation.output, axis=1) +if len(y_test.shape) == 2: + y_test = np.argmax(y_test, axis=1) +accuracy = np.mean(predictions == y_test) +print(f'validation, acc: {accuracy:.3f}, loss: {loss:.3f}') +