diff --git a/Bericht/Bilder/Convolution_2D.png b/Bericht/Bilder/Convolution_2D.png new file mode 100644 index 0000000000000000000000000000000000000000..4c1c805e2e920eb34e486636f39c6185e3f85612 Binary files /dev/null and b/Bericht/Bilder/Convolution_2D.png differ diff --git a/Bericht/Bilder/Convolution_2D.svg b/Bericht/Bilder/Convolution_2D.svg new file mode 100644 index 0000000000000000000000000000000000000000..d8584fc274cd610c55708fd0d990e7c1b2a0638d --- /dev/null +++ b/Bericht/Bilder/Convolution_2D.svg @@ -0,0 +1,1210 @@ +<?xml version="1.0" encoding="UTF-8" standalone="no"?> +<!-- Created with Inkscape (http://www.inkscape.org/) --> + +<svg + width="210mm" + height="100.2653mm" + viewBox="0 0 210 100.2653" + version="1.1" + id="svg5" + inkscape:version="1.1 (c68e22c387, 2021-05-23)" + sodipodi:docname="Convolution_2D.svg" + inkscape:export-filename="F:\RWTH\HiWi_IEHK\DAMASK3\Bericht\Bilder\Convolution_2D.png" + inkscape:export-xdpi="96" + inkscape:export-ydpi="96" + xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" + xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg"> + <sodipodi:namedview + id="namedview7" + pagecolor="#ffffff" + bordercolor="#666666" + borderopacity="1.0" + inkscape:pageshadow="2" + inkscape:pageopacity="0.0" + inkscape:pagecheckerboard="0" + inkscape:document-units="mm" + showgrid="true" + inkscape:zoom="1.0809568" + inkscape:cx="376.05573" + inkscape:cy="200.28552" + inkscape:window-width="1920" + inkscape:window-height="1017" + inkscape:window-x="-8" + inkscape:window-y="-8" + inkscape:window-maximized="1" + inkscape:current-layer="layer1" + fit-margin-top="0" + fit-margin-left="0" + fit-margin-right="0" + fit-margin-bottom="0"> + <inkscape:grid + type="xygrid" + id="grid824" + originx="-21.034021" + originy="-47.492358" /> + </sodipodi:namedview> + <defs + id="defs2" /> + <g + inkscape:label="Ebene 1" + inkscape:groupmode="layer" + id="layer1" + transform="translate(-21.034021,-47.492353)"> + <rect + style="fill:none;stroke:none;stroke-width:0.289593" + id="rect848" + width="209.7104" + height="99.9757" + x="21.178818" + y="47.63715" /> + <path + style="fill:none;stroke:#000000;stroke-width:0.429594;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" + d="M 29.104166,55.560856 V 135.05164" + id="path883" /> + <path + style="fill:none;stroke:#000000;stroke-width:0.429903;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" + d="M 42.333332,55.560856 V 135.16578" + id="path883-8" /> + <path + style="fill:none;stroke:#000000;stroke-width:0.428167;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" + d="M 55.562498,55.560856 V 134.52441" + id="path883-3" /> + <path + style="fill:none;stroke:#000000;stroke-width:0.428167;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" + d="M 68.791668,55.560856 V 134.52441" + id="path883-81" /> + <path + style="fill:none;stroke:#000000;stroke-width:0.429286;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" + d="M 82.020831,55.560856 V 134.9375" + id="path883-33" /> + <path + style="fill:none;stroke:#000000;stroke-width:0.429594;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" + d="M 95.250001,55.560856 V 135.05164" + id="path883-9" /> + <path + style="fill:none;stroke:#000000;stroke-width:0.429286;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" + d="M 108.47917,55.560856 V 134.9375" + id="path883-80" /> + <path + style="fill:none;stroke:#000000;stroke-width:0.430756;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" + d="m 29.126339,134.52469 79.352831,-0.023" + id="path883-7" /> + <path + style="fill:none;stroke:#000000;stroke-width:0.427475;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" + d="m 29.122695,121.36382 79.096945,-0.0228" + id="path883-8-9" /> + <path + style="fill:none;stroke:#000000;stroke-width:0.429212;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" + d="m 29.118996,108.20322 79.745994,-0.0228" + id="path883-3-4" /> + <path + style="fill:none;stroke:#000000;stroke-width:0.499419;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" + d="m 29.115889,95.127399 79.582561,-0.03087" + id="path883-81-2" /> + <path + style="fill:none;stroke:#000000;stroke-width:0.343014;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" + d="M 29.110906,81.797282 108.20925,81.78263" + id="path883-33-9" /> + <path + style="fill:none;stroke:#000000;stroke-width:0.428778;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" + d="m 29.107909,68.721451 79.583741,-0.02276" + id="path883-9-9" /> + <path + style="fill:none;stroke:#000000;stroke-width:0.42791;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" + d="m 29.104223,55.560859 79.259197,-0.02276" + id="path883-80-3" /> + <path + style="fill:#c7ddf2;fill-opacity:1;stroke:none;stroke-width:0.185949;stroke-miterlimit:4;stroke-dasharray:none" + d="m 42.708434,101.72207 v -6.214611 h 6.246994 6.246996 v 6.214611 6.21462 h -6.246996 -6.246994 z" + id="path1471" /> + <path + style="fill:#c7ddf2;fill-opacity:1;stroke:none;stroke-width:0.185949;stroke-miterlimit:4;stroke-dasharray:none" + d="m 42.708434,88.485754 v -6.376033 h 6.246994 6.246996 v 6.376033 6.37603 h -6.246996 -6.246994 z" + id="path1880" /> + <path + style="fill:#c7ddf2;fill-opacity:1;stroke:none;stroke-width:0.185949;stroke-miterlimit:4;stroke-dasharray:none" + d="m 42.708434,75.330142 v -6.295323 h 6.246994 6.246996 v 6.295323 6.295322 h -6.246996 -6.246994 z" + id="path1919" /> + <path + style="fill:#c7ddf2;fill-opacity:1;stroke:none;stroke-width:0.185949;stroke-miterlimit:4;stroke-dasharray:none" + d="m 55.851463,75.356101 v -6.321282 h 6.328125 6.328125 v 6.214615 6.214611 l -1.825421,2.47e-4 c -1.00398,1.78e-4 -3.851638,0.04817 -6.328125,0.106668 l -4.502704,0.106354 z" + id="path1958" /> + <path + style="fill:#c7ddf2;fill-opacity:1;stroke:none;stroke-width:0.185949;stroke-miterlimit:4;stroke-dasharray:none" + d="m 69.156753,75.249434 v -6.214615 h 6.246993 6.246997 v 6.214615 6.214611 h -6.246997 -6.246993 z" + id="path1997" /> + <path + style="fill:#c7ddf2;fill-opacity:1;stroke:none;stroke-width:0.185949;stroke-miterlimit:4;stroke-dasharray:none" + d="m 82.29978,75.249434 v -6.214615 h 6.328127 6.328125 v 6.214615 6.214611 H 88.627907 82.29978 Z" + id="path2036" /> + <path + style="fill:#c7ddf2;fill-opacity:1;stroke:none;stroke-width:0.185949;stroke-miterlimit:4;stroke-dasharray:none" + d="m 82.29978,88.510664 v -6.400943 h 6.328127 6.328125 v 6.295322 6.295323 l -4.259315,7.4e-4 c -2.342624,2.47e-4 -5.190282,0.04789 -6.328127,0.105621 l -2.06881,0.104957 z" + id="path2075" /> + <path + style="fill:#c7ddf2;fill-opacity:1;stroke:none;stroke-width:0.185949;stroke-miterlimit:4;stroke-dasharray:none" + d="m 69.156753,88.485754 v -6.376033 h 6.246993 6.246997 v 6.376033 6.37603 h -6.246997 -6.246993 z" + id="path2114" /> + <path + style="fill:#c7ddf2;fill-opacity:1;stroke:none;stroke-width:0.185949;stroke-miterlimit:4;stroke-dasharray:none" + d="m 55.851463,88.485754 v -6.376033 h 6.328125 6.328125 v 6.376033 6.37603 h -6.328125 -6.328125 z" + id="path2153" /> + <path + style="fill:#c7ddf2;fill-opacity:1;stroke:none;stroke-width:0.185949;stroke-miterlimit:4;stroke-dasharray:none" + d="m 55.851463,101.72207 v -6.214611 h 6.328125 6.328125 v 6.214611 6.21462 h -6.328125 -6.328125 z" + id="path2192" /> + <path + style="fill:#c7ddf2;fill-opacity:1;stroke:none;stroke-width:0.185949;stroke-miterlimit:4;stroke-dasharray:none" + d="m 69.156753,101.72207 v -6.214611 h 6.246993 6.246997 v 6.214611 6.21462 h -6.246997 -6.246993 z" + id="path2231" /> + <path + style="fill:#c7ddf2;fill-opacity:1;stroke:none;stroke-width:0.185949;stroke-miterlimit:4;stroke-dasharray:none" + d="m 82.29978,101.72207 v -6.214611 h 5.086697 c 2.797684,0 5.645341,-0.04698 6.328125,-0.104394 l 1.24143,-0.104398 v 6.319013 6.31901 H 88.627907 82.29978 Z" + id="path2270" /> + <path + style="fill:#c7ddf2;fill-opacity:1;stroke:none;stroke-width:0.185949;stroke-miterlimit:4;stroke-dasharray:none" + d="m 82.29978,114.71626 v -6.29532 h 6.328127 6.328125 v 6.29532 6.29533 H 88.627907 82.29978 Z" + id="path2309" /> + <path + style="fill:#c7ddf2;fill-opacity:1;stroke:none;stroke-width:0.185949;stroke-miterlimit:4;stroke-dasharray:none" + d="m 69.156753,114.71626 v -6.29532 h 6.246993 6.246997 v 6.29532 6.29533 h -6.246997 -6.246993 z" + id="path2348" /> + <path + style="fill:#c7ddf2;fill-opacity:1;stroke:none;stroke-width:0.185949;stroke-miterlimit:4;stroke-dasharray:none" + d="m 55.851463,114.71626 v -6.29532 h 6.328125 6.328125 v 6.29532 6.29533 h -6.328125 -6.328125 z" + id="path2387" /> + <path + style="fill:#c7ddf2;fill-opacity:1;stroke:none;stroke-width:0.185949;stroke-miterlimit:4;stroke-dasharray:none" + d="m 42.708434,114.71626 v -6.29532 h 6.246994 6.246996 v 6.29532 6.29533 h -6.246996 -6.246994 z" + id="path2426" /> + <text + xml:space="preserve" + style="font-size:5.27793px;line-height:1.25;font-family:sans-serif;stroke-width:0.247403" + x="34.184994" + y="64.212677" + id="text4821" + inkscape:transform-center-x="-2.7584132" + inkscape:transform-center-y="-1.9370211" + transform="scale(1.0026019,0.99740483)"><tspan + sodipodi:role="line" + id="tspan4819" + style="stroke-width:0.247403" + x="34.184994" + y="64.212677">0</tspan></text> + <text + xml:space="preserve" + style="font-size:5.27793px;line-height:1.25;font-family:sans-serif;stroke-width:0.247403" + x="34.184994" + y="77.367043" + id="text4821-9" + inkscape:transform-center-x="-2.7584132" + inkscape:transform-center-y="-1.9370229" + transform="scale(1.0026019,0.99740483)"><tspan + sodipodi:role="line" + id="tspan4819-2" + style="stroke-width:0.247403" + x="34.184994" + y="77.367043">0</tspan></text> + <text + xml:space="preserve" + style="font-size:5.27793px;line-height:1.25;font-family:sans-serif;stroke-width:0.247403" + x="34.184994" + y="90.602348" + id="text4821-7" + inkscape:transform-center-x="-2.7584132" + inkscape:transform-center-y="-1.9370197" + transform="scale(1.0026019,0.99740483)"><tspan + sodipodi:role="line" + id="tspan4819-21" + style="stroke-width:0.247403" + x="34.184994" + y="90.602348">0</tspan></text> + <text + xml:space="preserve" + style="font-size:5.27793px;line-height:1.25;font-family:sans-serif;stroke-width:0.247403" + x="34.184994" + y="103.83762" + id="text4821-3" + inkscape:transform-center-x="-2.7584132" + inkscape:transform-center-y="-1.9370256" + transform="scale(1.0026019,0.99740483)"><tspan + sodipodi:role="line" + id="tspan4819-1" + style="stroke-width:0.247403" + x="34.184994" + y="103.83762">0</tspan></text> + <text + xml:space="preserve" + style="font-size:5.27793px;line-height:1.25;font-family:sans-serif;stroke-width:0.247403" + x="34.184994" + y="116.992" + id="text4821-1" + inkscape:transform-center-x="-2.7584132" + inkscape:transform-center-y="-1.937034" + transform="scale(1.0026019,0.99740483)"><tspan + sodipodi:role="line" + id="tspan4819-8" + style="stroke-width:0.247403" + x="34.184994" + y="116.992">0</tspan></text> + <text + xml:space="preserve" + style="font-size:5.27793px;line-height:1.25;font-family:sans-serif;stroke-width:0.247403" + x="34.184994" + y="130.18684" + id="text4821-6" + inkscape:transform-center-x="-2.7584132" + inkscape:transform-center-y="-1.9370255" + transform="scale(1.0026019,0.99740483)"><tspan + sodipodi:role="line" + id="tspan4819-0" + style="stroke-width:0.247403" + x="34.184994" + y="130.18684">0</tspan></text> + <text + xml:space="preserve" + style="font-size:5.27793px;line-height:1.25;font-family:sans-serif;stroke-width:0.247403" + x="47.143188" + y="64.212677" + id="text4821-31" + inkscape:transform-center-x="-2.758411" + inkscape:transform-center-y="-1.9370211" + transform="scale(1.0026019,0.99740483)"><tspan + sodipodi:role="line" + id="tspan4819-24" + style="stroke-width:0.247403" + x="47.143188" + y="64.212677">0</tspan></text> + <text + xml:space="preserve" + style="font-size:5.27793px;line-height:1.25;font-family:sans-serif;stroke-width:0.247403" + x="60.904537" + y="64.212677" + id="text4821-19" + inkscape:transform-center-x="-2.7584139" + inkscape:transform-center-y="-1.9370211" + transform="scale(1.0026019,0.99740483)"><tspan + sodipodi:role="line" + id="tspan4819-3" + style="stroke-width:0.247403" + x="60.904537" + y="64.212677">0</tspan></text> + <text + xml:space="preserve" + style="font-size:5.27793px;line-height:1.25;font-family:sans-serif;stroke-width:0.247403" + x="73.53286" + y="64.212677" + id="text4821-8" + inkscape:transform-center-x="-2.758412" + inkscape:transform-center-y="-1.9370211" + transform="scale(1.0026019,0.99740483)"><tspan + sodipodi:role="line" + id="tspan4819-7" + style="stroke-width:0.247403" + x="73.53286" + y="64.212677">0</tspan></text> + <text + xml:space="preserve" + style="font-size:5.27793px;line-height:1.25;font-family:sans-serif;stroke-width:0.247403" + x="86.727692" + y="64.212677" + id="text4821-62" + inkscape:transform-center-x="-2.7584122" + inkscape:transform-center-y="-1.9370211" + transform="scale(1.0026019,0.99740483)"><tspan + sodipodi:role="line" + id="tspan4819-9" + style="stroke-width:0.247403" + x="86.727692" + y="64.212677">0</tspan></text> + <text + xml:space="preserve" + style="font-size:5.27793px;line-height:1.25;font-family:sans-serif;stroke-width:0.247403" + x="99.922523" + y="64.212677" + id="text4821-65" + inkscape:transform-center-x="-2.7584125" + inkscape:transform-center-y="-1.9370211" + transform="scale(1.0026019,0.99740483)"><tspan + sodipodi:role="line" + id="tspan4819-92" + style="stroke-width:0.247403" + x="99.922523" + y="64.212677">0</tspan></text> + <text + xml:space="preserve" + style="font-size:5.27793px;line-height:1.25;font-family:sans-serif;stroke-width:0.247403" + x="99.922523" + y="77.367043" + id="text4821-10" + inkscape:transform-center-x="-2.7584125" + inkscape:transform-center-y="-1.9370229" + transform="scale(1.0026019,0.99740483)"><tspan + sodipodi:role="line" + id="tspan4819-4" + style="stroke-width:0.247403" + x="99.922523" + y="77.367043">0</tspan></text> + <text + xml:space="preserve" + style="font-size:5.27793px;line-height:1.25;font-family:sans-serif;stroke-width:0.247403" + x="99.922523" + y="90.602348" + id="text4821-33" + inkscape:transform-center-x="-2.7584125" + inkscape:transform-center-y="-1.9370197" + transform="scale(1.0026019,0.99740483)"><tspan + sodipodi:role="line" + id="tspan4819-88" + style="stroke-width:0.247403" + x="99.922523" + y="90.602348">0</tspan></text> + <text + xml:space="preserve" + style="font-size:5.27793px;line-height:1.25;font-family:sans-serif;stroke-width:0.247403" + x="99.922523" + y="103.83762" + id="text4821-0" + inkscape:transform-center-x="-2.7584125" + inkscape:transform-center-y="-1.9370256" + transform="scale(1.0026019,0.99740483)"><tspan + sodipodi:role="line" + id="tspan4819-17" + style="stroke-width:0.247403" + x="99.922523" + y="103.83762">0</tspan></text> + <text + xml:space="preserve" + style="font-size:5.27793px;line-height:1.25;font-family:sans-serif;stroke-width:0.247403" + x="99.922523" + y="116.992" + id="text4821-2" + inkscape:transform-center-x="-2.7584125" + inkscape:transform-center-y="-1.937034" + transform="scale(1.0026019,0.99740483)"><tspan + sodipodi:role="line" + id="tspan4819-27" + style="stroke-width:0.247403" + x="99.922523" + y="116.992">0</tspan></text> + <text + xml:space="preserve" + style="font-size:5.27793px;line-height:1.25;font-family:sans-serif;stroke-width:0.247403" + x="99.922523" + y="130.18684" + id="text4821-91" + inkscape:transform-center-x="-2.7584125" + inkscape:transform-center-y="-1.9370255" + transform="scale(1.0026019,0.99740483)"><tspan + sodipodi:role="line" + id="tspan4819-6" + style="stroke-width:0.247403" + x="99.922523" + y="130.18684">0</tspan></text> + <text + xml:space="preserve" + style="font-size:5.27793px;line-height:1.25;font-family:sans-serif;stroke-width:0.247403" + x="86.727692" + y="130.18684" + id="text4821-79" + inkscape:transform-center-x="-2.7584122" + inkscape:transform-center-y="-1.9370255" + transform="scale(1.0026019,0.99740483)"><tspan + sodipodi:role="line" + id="tspan4819-63" + style="stroke-width:0.247403" + x="86.727692" + y="130.18684">0</tspan></text> + <text + xml:space="preserve" + style="font-size:5.27793px;line-height:1.25;font-family:sans-serif;stroke-width:0.247403" + x="73.53286" + y="130.18684" + id="text4821-15" + inkscape:transform-center-x="-2.758412" + inkscape:transform-center-y="-1.9370255" + transform="scale(1.0026019,0.99740483)"><tspan + sodipodi:role="line" + id="tspan4819-85" + style="stroke-width:0.247403" + x="73.53286" + y="130.18684">0</tspan></text> + <text + xml:space="preserve" + style="font-size:5.27793px;line-height:1.25;font-family:sans-serif;stroke-width:0.247403" + x="60.33802" + y="130.18684" + id="text4821-90" + inkscape:transform-center-x="-2.7584112" + inkscape:transform-center-y="-1.9370255" + transform="scale(1.0026019,0.99740483)"><tspan + sodipodi:role="line" + id="tspan4819-78" + style="stroke-width:0.247403" + x="60.33802" + y="130.18684">0</tspan></text> + <text + xml:space="preserve" + style="font-size:5.27793px;line-height:1.25;font-family:sans-serif;stroke-width:0.247403" + x="47.143188" + y="130.18684" + id="text4821-63" + inkscape:transform-center-x="-2.758411" + inkscape:transform-center-y="-1.9370255" + transform="scale(1.0026019,0.99740483)"><tspan + sodipodi:role="line" + id="tspan4819-00" + style="stroke-width:0.247403" + x="47.143188" + y="130.18684">0</tspan></text> + <text + xml:space="preserve" + style="font-size:5.27793px;line-height:1.25;font-family:sans-serif;stroke-width:0.247403" + x="47.095512" + y="77.369621" + id="text7980" + transform="scale(1.0026019,0.99740483)"><tspan + sodipodi:role="line" + id="tspan7978" + style="stroke-width:0.247403" + x="47.095512" + y="77.369621">1</tspan></text> + <text + xml:space="preserve" + style="font-size:5.27793px;line-height:1.25;font-family:sans-serif;stroke-width:0.247403" + x="60.974117" + y="77.404411" + id="text9128" + transform="scale(1.0026019,0.99740483)"><tspan + sodipodi:role="line" + id="tspan9126" + style="stroke-width:0.247403" + x="60.974117" + y="77.404411">2</tspan></text> + <text + xml:space="preserve" + style="font-size:5.27793px;line-height:1.25;font-family:sans-serif;stroke-width:0.247403" + x="73.541878" + y="77.367043" + id="text9748" + transform="scale(1.0026019,0.99740483)"><tspan + sodipodi:role="line" + id="tspan9746" + style="stroke-width:0.247403" + x="73.541878" + y="77.367043">3</tspan></text> + <text + xml:space="preserve" + style="font-size:5.27793px;line-height:1.25;font-family:sans-serif;stroke-width:0.247403" + x="86.745735" + y="77.369621" + id="text10434" + transform="scale(1.0026019,0.99740483)"><tspan + sodipodi:role="line" + id="tspan10432" + style="stroke-width:0.247403" + x="86.745735" + y="77.369621">4</tspan></text> + <text + xml:space="preserve" + style="font-size:5.27793px;line-height:1.25;font-family:sans-serif;stroke-width:0.247403" + x="47.168961" + y="90.567551" + id="text11692" + transform="scale(1.0026019,0.99740483)"><tspan + sodipodi:role="line" + id="tspan11690" + style="stroke-width:0.247403" + x="47.168961" + y="90.567551">5</tspan></text> + <text + xml:space="preserve" + style="font-size:5.27793px;line-height:1.25;font-family:sans-serif;stroke-width:0.247403" + x="60.885204" + y="90.602348" + id="text12114" + transform="scale(1.0026019,0.99740483)"><tspan + sodipodi:role="line" + id="tspan12112" + style="stroke-width:0.247403" + x="60.885204" + y="90.602348">6</tspan></text> + <text + xml:space="preserve" + style="font-size:5.27793px;line-height:1.25;font-family:sans-serif;stroke-width:0.247403" + x="73.540596" + y="90.604919" + id="text12976" + transform="scale(1.0026019,0.99740483)"><tspan + sodipodi:role="line" + id="tspan12974" + style="stroke-width:0.247403" + x="73.540596" + y="90.604919">7</tspan></text> + <text + xml:space="preserve" + style="font-size:5.27793px;line-height:1.25;font-family:sans-serif;stroke-width:0.247403" + x="86.727692" + y="90.602348" + id="text13596" + transform="scale(1.0026019,0.99740483)"><tspan + sodipodi:role="line" + id="tspan13594" + style="stroke-width:0.247403" + x="86.727692" + y="90.602348">8</tspan></text> + <text + xml:space="preserve" + style="font-size:5.27793px;line-height:1.25;font-family:sans-serif;stroke-width:0.247403" + x="47.161228" + y="103.83762" + id="text18880" + transform="scale(1.0026019,0.99740483)"><tspan + sodipodi:role="line" + id="tspan18878" + style="stroke-width:0.247403" + x="47.161228" + y="103.83762">9</tspan></text> + <text + xml:space="preserve" + style="font-size:5.27793px;line-height:1.25;font-family:sans-serif;stroke-width:0.247403" + x="59.109577" + y="103.83762" + id="text21106" + transform="scale(1.0026019,0.99740483)"><tspan + sodipodi:role="line" + id="tspan21104" + style="stroke-width:0.247403" + x="59.109577" + y="103.83762">10</tspan></text> + <text + xml:space="preserve" + style="font-size:5.27793px;line-height:1.25;font-family:sans-serif;stroke-width:0.247403" + x="71.80619" + y="103.84021" + id="text23706" + transform="scale(1.0026019,0.99740483)"><tspan + sodipodi:role="line" + id="tspan23704" + style="stroke-width:0.247403" + x="71.80619" + y="103.84021">11</tspan></text> + <text + xml:space="preserve" + style="font-size:5.27793px;line-height:1.25;font-family:sans-serif;stroke-width:0.247403" + x="85.021637" + y="103.87498" + id="text24326" + transform="scale(1.0026019,0.99740483)"><tspan + sodipodi:role="line" + id="tspan24324" + style="stroke-width:0.247403" + x="85.021637" + y="103.87498">12</tspan></text> + <text + xml:space="preserve" + style="font-size:5.27793px;line-height:1.25;font-family:sans-serif;stroke-width:0.247403" + x="45.384312" + y="116.992" + id="text29342" + transform="scale(1.0026019,0.99740483)"><tspan + sodipodi:role="line" + id="tspan29340" + style="stroke-width:0.247403" + x="45.384312" + y="116.992">13</tspan></text> + <text + xml:space="preserve" + style="font-size:5.27793px;line-height:1.25;font-family:sans-serif;stroke-width:0.247403" + x="59.082516" + y="116.99458" + id="text29984" + transform="scale(1.0026019,0.99740483)"><tspan + sodipodi:role="line" + id="tspan29982" + style="stroke-width:0.247403" + x="59.082516" + y="116.99458">14</tspan></text> + <text + xml:space="preserve" + style="font-size:5.27793px;line-height:1.25;font-family:sans-serif;stroke-width:0.247403" + x="71.793304" + y="116.95721" + id="text31182" + transform="scale(1.0026019,0.99740483)"><tspan + sodipodi:role="line" + id="tspan31180" + style="stroke-width:0.247403" + x="71.793304" + y="116.95721">15</tspan></text> + <text + xml:space="preserve" + style="font-size:5.27793px;line-height:1.25;font-family:sans-serif;stroke-width:0.247403" + x="84.923714" + y="116.992" + id="text32296" + transform="scale(1.0026019,0.99740483)"><tspan + sodipodi:role="line" + id="tspan32294" + style="stroke-width:0.247403" + x="84.923714" + y="116.992">16</tspan></text> + <rect + style="fill:none;fill-opacity:1;stroke:#cc071e;stroke-width:0.84530096;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;stroke-dashoffset:0" + id="rect34652" + width="40.052528" + height="39.946598" + x="29.104223" + y="55.56086" /> + <rect + style="fill:none;fill-opacity:1;stroke:#cc071e;stroke-width:0.82892902;stroke-miterlimit:4;stroke-dasharray:2.48678706,0.82892902;stroke-opacity:1;stroke-dashoffset:0" + id="rect34652-4" + width="40.059753" + height="38.407337" + x="42.32972" + y="56.418869" /> + <path + style="fill:none;stroke:#000000;stroke-width:0.404337;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" + d="m 122.03577,78.042596 h 36.30886" + id="path35078" /> + <path + style="fill:none;stroke:#000000;stroke-width:0.404337;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" + d="m 122.03577,90.785368 h 36.30886" + id="path35078-1" /> + <path + style="fill:none;stroke:#000000;stroke-width:0.403441;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" + d="m 122.19647,103.52816 h 36.14816" + id="path35078-4" /> + <path + style="fill:none;stroke:#000000;stroke-width:0.403142;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" + d="m 122.25003,116.27097 h 36.0946" + id="path35078-12" /> + <g + id="g35249" + transform="matrix(0.00254819,0.90870613,-0.8754014,0.00264514,227.23714,-50.905079)"> + <path + style="fill:none;stroke:#000000;stroke-width:0.458;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" + d="m 141.56748,79.375027 h 42.33333" + id="path35078-8" /> + <path + style="fill:none;stroke:#000000;stroke-width:0.458;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" + d="m 141.56235,93.04516 h 42.33333" + id="path35078-1-4" /> + <path + style="fill:none;stroke:#000000;stroke-width:0.458;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" + d="m 141.55721,106.71529 h 42.33333" + id="path35078-4-4" /> + <path + style="fill:none;stroke:#000000;stroke-width:0.458;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" + d="m 141.55208,120.38541 h 42.33333" + id="path35078-12-6" /> + </g> + <path + style="fill:none;stroke:#000000;stroke-width:0.458;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" + d="M 169.33333,69.850002 H 222.25" + id="path987" /> + <path + style="fill:none;stroke:#000000;stroke-width:0.458;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" + d="M 169.33333,83.079169 H 222.25" + id="path987-4" /> + <path + style="fill:none;stroke:#000000;stroke-width:0.458;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" + d="M 169.33333,96.308336 H 222.25" + id="path987-8" /> + <path + style="fill:none;stroke:#000000;stroke-width:0.458;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" + d="M 169.33333,109.53752 H 222.25" + id="path987-90" /> + <path + style="fill:none;stroke:#000000;stroke-width:0.458;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" + d="M 169.33333,122.76669 H 222.25" + id="path987-1" /> + <path + style="fill:none;stroke:#000000;stroke-width:0.458;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" + d="M 169.33333,69.850002 V 122.76669" + id="path987-9" /> + <path + style="fill:none;stroke:#000000;stroke-width:0.458;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" + d="M 182.56249,69.850002 V 122.76669" + id="path987-9-3" /> + <path + style="fill:none;stroke:#000000;stroke-width:0.458;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" + d="M 195.79166,69.850002 V 122.76669" + id="path987-9-4" /> + <path + style="fill:none;stroke:#000000;stroke-width:0.458;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" + d="M 209.02083,69.850002 V 122.76669" + id="path987-9-0" /> + <path + style="fill:none;stroke:#000000;stroke-width:0.458;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" + d="M 222.25,69.850002 V 122.76669" + id="path987-9-03" /> + <text + xml:space="preserve" + style="font-style:normal;font-weight:normal;font-size:10.5833px;line-height:1.25;font-family:sans-serif;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.264583" + x="187.85417" + y="74.083328" + id="text20517"><tspan + sodipodi:role="line" + id="tspan20515" + style="stroke-width:0.264583" + x="187.85417" + y="74.083328" /></text> + <path + style="fill:#cc071e;fill-opacity:1;stroke:none;stroke-width:1.13235;stroke-miterlimit:4;stroke-dasharray:none" + d="M -176.29315,69.012717 V 46.117503 h 21.58692 21.58691 v 22.895214 22.895214 h -21.58691 -21.58692 z" + id="path48940" + transform="matrix(0.26458333,0,0,0.26458333,169.10433,66.145833)" /> + <path + style="fill:#cc071e;fill-opacity:1;stroke:none;stroke-width:1.13235;stroke-miterlimit:4;stroke-dasharray:none" + d="m -130.72483,80.623861 c -0.23542,-6.206238 -0.42894,-16.509085 -0.43004,-22.895214 l -0.002,-11.611144 h 21.58692 21.586913 v 22.895214 22.895214 h -21.156883 -21.15687 z" + id="path49317" + transform="matrix(0.26458333,0,0,0.26458333,169.10433,66.145833)" /> + <path + style="fill:#cc071e;fill-opacity:1;stroke:none;stroke-width:1.13235;stroke-miterlimit:4;stroke-dasharray:none" + d="M -85.366441,69.012717 V 46.117503 h 21.259842 21.259841 v 15.924888 c 0,8.758689 0.191918,19.061536 0.426484,22.895214 l 0.426483,6.970326 h -21.686325 -21.686325 z" + id="path49356" + transform="matrix(0.26458333,0,0,0.26458333,169.10433,66.145833)" /> + <path + style="fill:#cc071e;fill-opacity:1;stroke:none;stroke-width:1.13235;stroke-miterlimit:4;stroke-dasharray:none" + d="M -85.366441,117.41974 V 94.524527 h 21.586916 21.586916 v 22.895213 22.89521 h -21.586916 -21.586916 z" + id="path49395" + transform="matrix(0.26458333,0,0,0.26458333,169.10433,66.145833)" /> + <path + style="fill:#cc071e;fill-opacity:1;stroke:none;stroke-width:1.13235;stroke-miterlimit:4;stroke-dasharray:none" + d="M -130.50272,117.41974 V 94.524527 h 21.15521 21.155214 l 0.431704,15.805503 c 0.237437,8.69302 0.431704,18.99587 0.431704,22.89521 v 7.08971 h -21.586912 -21.58692 z" + id="path49434" + transform="matrix(0.26458333,0,0,0.26458333,169.10433,66.145833)" /> + <path + style="fill:#cc071e;fill-opacity:1;stroke:none;stroke-width:1.13235;stroke-miterlimit:4;stroke-dasharray:none" + d="m -175.64085,129.68503 c -0.001,-5.84645 -0.19474,-16.1493 -0.4305,-22.89521 l -0.42866,-12.265293 h 21.69035 21.69034 v 22.895213 22.89521 h -21.25984 -21.25984 z" + id="path49473" + transform="matrix(0.26458333,0,0,0.26458333,169.10433,66.145833)" /> + <path + style="fill:#cc071e;fill-opacity:1;stroke:none;stroke-width:1.13235;stroke-miterlimit:4;stroke-dasharray:none" + d="M -175.639,165.17262 V 142.2774 h 21.16385 21.16386 l 0.42306,5.00482 c 0.23269,2.75264 0.42306,13.05549 0.42306,22.89521 v 17.8904 h -21.58691 -21.58692 z" + id="path49512" + transform="matrix(0.26458333,0,0,0.26458333,169.10433,66.145833)" /> + <path + style="fill:#cc071e;fill-opacity:1;stroke:none;stroke-width:1.13235;stroke-miterlimit:4;stroke-dasharray:none" + d="M -130.50272,165.17262 V 142.2774 h 21.58692 21.586912 v 22.89522 22.89521 h -21.586912 -21.58692 z" + id="path49551" + transform="matrix(0.26458333,0,0,0.26458333,169.10433,66.145833)" /> + <path + style="fill:#cc071e;fill-opacity:1;stroke:none;stroke-width:1.13235;stroke-miterlimit:4;stroke-dasharray:none" + d="M -85.366441,165.17262 V 142.2774 h 21.586916 21.586916 v 22.89522 22.89521 h -21.586916 -21.586916 z" + id="path49590" + transform="matrix(0.26458333,0,0,0.26458333,169.10433,66.145833)" /> + <text + xml:space="preserve" + style="font-size:5.03429px;line-height:1.25;font-family:sans-serif;stroke-width:0.235982" + x="141.25873" + y="84.685165" + id="text4821-65-4" + inkscape:transform-center-x="-2.5757066" + inkscape:transform-center-y="-1.8873168" + transform="scale(0.98150357,1.018845)"><tspan + sodipodi:role="line" + id="tspan4819-92-2" + style="stroke-width:0.235982" + x="141.25873" + y="84.685165">0</tspan></text> + <text + xml:space="preserve" + style="font-size:5.03429px;line-height:1.25;font-family:sans-serif;stroke-width:0.235982" + x="153.4511" + y="84.685165" + id="text4821-65-7" + inkscape:transform-center-x="-2.5757061" + inkscape:transform-center-y="-1.8873168" + transform="scale(0.98150357,1.018845)"><tspan + sodipodi:role="line" + id="tspan4819-92-9" + style="stroke-width:0.235982" + x="153.4511" + y="84.685165">0</tspan></text> + <text + xml:space="preserve" + style="font-size:5.03429px;line-height:1.25;font-family:sans-serif;stroke-width:0.235982" + x="153.4511" + y="97.192245" + id="text4821-65-70" + inkscape:transform-center-x="-2.5757061" + inkscape:transform-center-y="-1.8873208" + transform="scale(0.98150357,1.018845)"><tspan + sodipodi:role="line" + id="tspan4819-92-8" + style="stroke-width:0.235982" + x="153.4511" + y="97.192245">0</tspan></text> + <text + xml:space="preserve" + style="font-size:5.03429px;line-height:1.25;font-family:sans-serif;stroke-width:0.235982" + x="141.25873" + y="109.69936" + id="text4821-65-1" + inkscape:transform-center-x="-2.5757066" + inkscape:transform-center-y="-1.887317" + transform="scale(0.98150357,1.018845)"><tspan + sodipodi:role="line" + id="tspan4819-92-4" + style="stroke-width:0.235982" + x="141.25873" + y="109.69936">0</tspan></text> + <text + xml:space="preserve" + style="font-size:5.03429px;line-height:1.25;font-family:sans-serif;stroke-width:0.235982" + x="129.06635" + y="109.69936" + id="text4821-65-705" + inkscape:transform-center-x="-2.5757056" + inkscape:transform-center-y="-1.887317" + transform="scale(0.98150357,1.018845)"><tspan + sodipodi:role="line" + id="tspan4819-92-3" + style="stroke-width:0.235982" + x="129.06635" + y="109.69936">0</tspan></text> + <text + xml:space="preserve" + style="font-size:5.03429px;line-height:1.25;font-family:sans-serif;stroke-width:0.235982" + x="129.06635" + y="97.192245" + id="text4821-65-5" + inkscape:transform-center-x="-2.5757056" + inkscape:transform-center-y="-1.8873208" + transform="scale(0.98150357,1.018845)"><tspan + sodipodi:role="line" + id="tspan4819-92-1" + style="stroke-width:0.235982" + x="129.06635" + y="97.192245">0</tspan></text> + <text + xml:space="preserve" + style="font-size:5.03429px;line-height:1.25;font-family:sans-serif;stroke-width:0.235982" + x="129.02087" + y="84.687622" + id="text40270" + transform="scale(0.98150357,1.018845)"><tspan + sodipodi:role="line" + id="tspan40268" + style="stroke-width:0.235982" + x="129.02087" + y="84.687622">1</tspan></text> + <text + xml:space="preserve" + style="font-size:5.03429px;line-height:1.25;font-family:sans-serif;stroke-width:0.235982" + x="141.21326" + y="97.194702" + id="text41264" + transform="scale(0.98150357,1.018845)"><tspan + sodipodi:role="line" + id="tspan41262" + style="stroke-width:0.235982" + x="141.21326" + y="97.194702">1</tspan></text> + <text + xml:space="preserve" + style="font-size:5.03429px;line-height:1.25;font-family:sans-serif;stroke-width:0.235982" + x="153.40562" + y="109.70181" + id="text41994" + transform="scale(0.98150357,1.018845)"><tspan + sodipodi:role="line" + id="tspan41992" + style="stroke-width:0.235982" + x="153.40562" + y="109.70181">1</tspan></text> + <path + style="fill:#00549f;fill-opacity:1;stroke:none;stroke-width:0.0925105" + d="m 169.59387,76.45873 v -6.302769 h 6.36396 6.36396 v 6.302769 6.302769 h -6.36396 -6.36396 z" + id="path1234" /> + <path + style="fill:#00549f;fill-opacity:1;stroke:none;stroke-width:0.0925105" + d="m 182.81132,76.45873 v -6.302769 h 6.36396 6.36396 v 6.302769 6.302769 h -6.36396 -6.36396 z" + id="path1421" /> + <path + style="fill:#00549f;fill-opacity:1;stroke:none;stroke-width:0.0925105" + d="m 196.02878,76.45873 v -6.302769 h 6.36396 6.36396 v 6.302769 6.302769 h -6.36396 -6.36396 z" + id="path1460" /> + <path + style="fill:#00549f;fill-opacity:1;stroke:none;stroke-width:0.0925105" + d="m 209.36862,76.45873 v -6.302769 h 6.30277 6.30277 v 6.302769 6.302769 h -6.30277 -6.30277 z" + id="path1499" /> + <path + style="fill:#00549f;fill-opacity:1;stroke:none;stroke-width:0.0925105" + d="m 209.36862,89.676187 v -6.302769 h 6.30277 6.30277 v 6.302769 6.302769 h -6.30277 -6.30277 z" + id="path1538" /> + <path + style="fill:#00549f;fill-opacity:1;stroke:none;stroke-width:0.0925105" + d="m 196.02878,89.676187 v -6.302769 h 6.36396 6.36396 v 6.302769 6.302769 h -6.36396 -6.36396 z" + id="path1577" /> + <path + style="fill:#00549f;fill-opacity:1;stroke:none;stroke-width:0.0925105" + d="m 182.81132,89.676187 v -6.302769 h 6.36396 6.36396 v 6.302769 6.302769 h -6.36396 -6.36396 z" + id="path1616" /> + <path + style="fill:#00549f;fill-opacity:1;stroke:none;stroke-width:0.0925105" + d="m 169.59387,89.676187 v -6.302769 h 6.36396 6.36396 v 6.302769 6.302769 h -6.36396 -6.36396 z" + id="path1655" /> + <path + style="fill:#00549f;fill-opacity:1;stroke:none;stroke-width:0.0925105" + d="m 169.59387,102.89366 v -6.302785 h 6.36396 6.36396 v 6.302785 6.30277 h -6.36396 -6.36396 z" + id="path1694" /> + <path + style="fill:#00549f;fill-opacity:1;stroke:none;stroke-width:0.0925105" + d="m 169.59387,102.89366 v -6.302785 h 6.36396 6.36396 v 6.302785 6.30277 h -6.36396 -6.36396 z" + id="path1733" /> + <path + style="fill:#00549f;fill-opacity:1;stroke:none;stroke-width:0.0925105" + d="m 182.81132,102.89366 v -6.302785 h 6.36396 6.36396 v 6.302785 6.30277 h -6.36396 -6.36396 z" + id="path1772" /> + <path + style="fill:#00549f;fill-opacity:1;stroke:none;stroke-width:0.0925105" + d="m 196.02878,102.89366 v -6.302785 h 6.36396 6.36396 v 6.302785 6.30277 h -6.36396 -6.36396 z" + id="path1811" /> + <path + style="fill:#00549f;fill-opacity:1;stroke:none;stroke-width:0.0925105" + d="m 209.36862,102.89366 v -6.302785 h 6.30277 6.30277 v 6.302785 6.30277 h -6.30277 -6.30277 z" + id="path1850" /> + <path + style="fill:#00549f;fill-opacity:1;stroke:none;stroke-width:0.0925105" + d="m 209.36862,116.17231 v -6.36396 h 6.30277 6.30277 v 6.36396 6.36396 h -6.30277 -6.30277 z" + id="path1889" /> + <path + style="fill:#00549f;fill-opacity:1;stroke:none;stroke-width:0.0925105" + d="m 196.02878,116.17231 v -6.36396 h 6.36396 6.36396 v 6.36396 6.36396 h -6.36396 -6.36396 z" + id="path1928" /> + <path + style="fill:#00549f;fill-opacity:1;stroke:none;stroke-width:0.0925105" + d="m 182.81132,116.17231 v -6.36396 h 6.36396 6.36396 v 6.36396 6.36396 h -6.36396 -6.36396 z" + id="path1967" /> + <path + style="fill:#00549f;fill-opacity:1;stroke:none;stroke-width:0.0925105" + d="m 169.59387,116.17231 v -6.36396 h 6.36396 6.36396 v 6.36396 6.36396 h -6.36396 -6.36396 z" + id="path2006" /> + <text + xml:space="preserve" + style="font-style:normal;font-weight:normal;font-size:4.93889px;line-height:1.25;font-family:sans-serif;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.264583" + x="174.38521" + y="78.338844" + id="text3481"><tspan + sodipodi:role="line" + id="tspan3479" + style="font-size:4.93889px;stroke-width:0.264583" + x="174.38521" + y="78.338844">7</tspan></text> + <text + xml:space="preserve" + style="font-size:4.9389px;line-height:1.25;font-family:sans-serif;stroke-width:0.264583" + x="187.62402" + y="78.336433" + id="text26563"><tspan + sodipodi:role="line" + id="tspan26561" + style="stroke-width:0.264583" + x="187.62402" + y="78.336433">9</tspan></text> + <text + xml:space="preserve" + style="font-size:4.9389px;line-height:1.25;font-family:sans-serif;stroke-width:0.264583" + x="199.22057" + y="78.338844" + id="text28305"><tspan + sodipodi:role="line" + id="tspan28303" + style="stroke-width:0.264583" + x="199.22057" + y="78.338844">11</tspan></text> + <text + xml:space="preserve" + style="font-size:4.9389px;line-height:1.25;font-family:sans-serif;stroke-width:0.264583" + x="214.08235" + y="78.338844" + id="text28793"><tspan + sodipodi:role="line" + id="tspan28791" + style="stroke-width:0.264583" + x="214.08235" + y="78.338844">4</tspan></text> + <text + xml:space="preserve" + style="font-size:4.9389px;line-height:1.25;font-family:sans-serif;stroke-width:0.264583" + x="172.75015" + y="91.533043" + id="text30093"><tspan + sodipodi:role="line" + id="tspan30091" + style="stroke-width:0.264583" + x="172.75015" + y="91.533043">15</tspan></text> + <text + xml:space="preserve" + style="font-size:4.9389px;line-height:1.25;font-family:sans-serif;stroke-width:0.264583" + x="185.93231" + y="91.565598" + id="text31615"><tspan + sodipodi:role="line" + id="tspan31613" + style="stroke-width:0.264583" + x="185.93231" + y="91.565598">18</tspan></text> + <text + xml:space="preserve" + style="font-size:4.9389px;line-height:1.25;font-family:sans-serif;stroke-width:0.264583" + x="199.311" + y="91.600571" + id="text34119"><tspan + sodipodi:role="line" + id="tspan34117" + style="stroke-width:0.264583" + x="199.311" + y="91.600571">21</tspan></text> + <text + xml:space="preserve" + style="font-size:4.9389px;line-height:1.25;font-family:sans-serif;stroke-width:0.264583" + x="212.44972" + y="91.568008" + id="text34899"><tspan + sodipodi:role="line" + id="tspan34897" + style="stroke-width:0.264583" + x="212.44972" + y="91.568008">11</tspan></text> + <text + xml:space="preserve" + style="font-size:4.9389px;line-height:1.25;font-family:sans-serif;stroke-width:0.264583" + x="172.82251" + y="104.79475" + id="text35783"><tspan + sodipodi:role="line" + id="tspan35781" + style="stroke-width:0.264583" + x="172.82251" + y="104.79475">23</tspan></text> + <text + xml:space="preserve" + style="font-size:4.9389px;line-height:1.25;font-family:sans-serif;stroke-width:0.264583" + x="186.01068" + y="104.79475" + id="text38053"><tspan + sodipodi:role="line" + id="tspan38051" + style="stroke-width:0.264583" + x="186.01068" + y="104.79475">30</tspan></text> + <text + xml:space="preserve" + style="font-size:4.9389px;line-height:1.25;font-family:sans-serif;stroke-width:0.264583" + x="199.27362" + y="104.79475" + id="text40763"><tspan + sodipodi:role="line" + id="tspan40761" + style="stroke-width:0.264583" + x="199.27362" + y="104.79475">33</tspan></text> + <text + xml:space="preserve" + style="font-size:4.9389px;line-height:1.25;font-family:sans-serif;stroke-width:0.264583" + x="212.39546" + y="104.79475" + id="text41559"><tspan + sodipodi:role="line" + id="tspan41557" + style="stroke-width:0.264583" + x="212.39546" + y="104.79475">19</tspan></text> + <text + xml:space="preserve" + style="font-size:4.9389px;line-height:1.25;font-family:sans-serif;stroke-width:0.264583" + x="172.73207" + y="118.02393" + id="text43811"><tspan + sodipodi:role="line" + id="tspan43809" + style="stroke-width:0.264583" + x="172.73207" + y="118.02393">13</tspan></text> + <text + xml:space="preserve" + style="font-size:4.9389px;line-height:1.25;font-family:sans-serif;stroke-width:0.264583" + x="186.05168" + y="118.02393" + id="text44937"><tspan + sodipodi:role="line" + id="tspan44935" + style="stroke-width:0.264583" + x="186.05168" + y="118.02393">23</tspan></text> + <text + xml:space="preserve" + style="font-size:4.9389px;line-height:1.25;font-family:sans-serif;stroke-width:0.264583" + x="199.29893" + y="118.02393" + id="text45469"><tspan + sodipodi:role="line" + id="tspan45467" + style="stroke-width:0.264583" + x="199.29893" + y="118.02393">25</tspan></text> + <text + xml:space="preserve" + style="font-size:4.9389px;line-height:1.25;font-family:sans-serif;stroke-width:0.264583" + x="212.52327" + y="118.05886" + id="text46231"><tspan + sodipodi:role="line" + id="tspan46229" + style="stroke-width:0.264583" + x="212.52327" + y="118.05886">27</tspan></text> + <text + xml:space="preserve" + style="font-size:5.64444px;line-height:1.25;font-family:sans-serif;stroke-width:0.264583" + x="133.1425" + y="75.155624" + id="text7607"><tspan + sodipodi:role="line" + id="tspan7605" + style="stroke-width:0.264583" + x="133.1425" + y="75.155624">Filter</tspan></text> + <text + xml:space="preserve" + style="font-size:5.64444px;line-height:1.25;font-family:sans-serif;stroke-width:0.264583" + x="186.08247" + y="67.218124" + id="text7607-0"><tspan + sodipodi:role="line" + id="tspan7605-0" + style="stroke-width:0.264583" + x="186.08247" + y="67.218124">Output</tspan></text> + <text + xml:space="preserve" + style="font-size:5.64444px;line-height:1.25;font-family:sans-serif;stroke-width:0.264583" + x="63.02792" + y="53.988956" + id="text7607-5"><tspan + sodipodi:role="line" + id="tspan7605-3" + style="stroke-width:0.264583" + x="63.02792" + y="53.988956">Input</tspan></text> + <text + xml:space="preserve" + style="font-size:5.64444px;line-height:1.25;font-family:sans-serif;fill:#cc071e;fill-opacity:1;stroke:#cc071e;stroke-width:0.264583;stroke-opacity:1" + x="-97.093979" + y="25.903534" + id="text7607-9" + transform="rotate(-90)"><tspan + sodipodi:role="line" + id="tspan7605-9" + style="fill:#cc071e;fill-opacity:1;stroke:#cc071e;stroke-width:0.264583;stroke-opacity:1" + x="-97.093979" + y="25.903534">Receptive Field</tspan></text> + </g> +</svg> diff --git a/Bericht/Bilder/grains.png b/Bericht/Bilder/grains.png new file mode 100644 index 0000000000000000000000000000000000000000..6bf364b7a2dc75efe1373a2850b9aa7a5650007e Binary files /dev/null and b/Bericht/Bilder/grains.png differ diff --git a/Bericht/Bilder/stress.png b/Bericht/Bilder/stress.png new file mode 100644 index 0000000000000000000000000000000000000000..decf4a02203b079a295d2c4272315ac6c841cae5 Binary files /dev/null and b/Bericht/Bilder/stress.png differ diff --git a/Notes.txt b/Notes.txt index a1e16b6e6801ecc536ccc8d90939b7d9ff192a05..b1f9a295285343b86809e17b9a7058f71263b243 100644 --- a/Notes.txt +++ b/Notes.txt @@ -8,8 +8,10 @@ V9: 3 layer, doppelte depth Conv pro layer, norm. Daten,kernel 5, phase only V10: 3 layer, eine Conv pro layer, norm Daten, phase only V11: 3 layer, doppel Conv, normDaten, phase + angle V12: 3 layer, doppel Conv, normDataen,phase 64 -V13: 4 layer, doppel Conv, normDataen,phase +V13: 4 layer, doppel Conv, normDataen,phase 64 V14: 4 layer, single conv, normDataen,phase + angle 64 +V15: 3 layer, doppelte depth Conv pro layer, norm. Daten,kernel 7, phase only, dropout 0.3,32 +V16: 3 layer, doppelte depth Conv pro layer, norm. Daten,kernel 7, angelsonly, dropout 0.5, 32 V9 mit kernel 7 und nur den phasen: mean error over whole set: 16.91116704929035 max error average: 292.8658473955995 and maximum 814.873957640188 diff --git a/UNet/UNet_V10.py b/UNet/UNet_V10.py index ed8320cc84c52d9d3eba9e067282eb266e71a0ad..31a0a9975ba2c533f5f12f6bf52ed61dd3b36309 100644 --- a/UNet/UNet_V10.py +++ b/UNet/UNet_V10.py @@ -50,18 +50,16 @@ class head_layer(nn.Module): #return self.sig(self.pointwise(self.depthwise(x))) #convolution class Encoder(nn.Module): - def __init__(self,kernel_size, chs, padding=(0,"same","same")): + def __init__(self,kernel_size, chs, padding=("same","same","same")): super().__init__() self.channels = chs self.enc_blocks = nn.ModuleList([depthwise_separable_conv(chs[i][0], chs[i][1],kernel_size=kernel_size, padding=padding[i]) for i in range(len(chs))]) self.pool = nn.MaxPool3d(kernel_size=2, stride=2) #self.batch_norm = nn.ModuleList([nn.BatchNorm3d( chs[i][2]) for i in range(len(chs))]) - self.periodic_upsample = nn.ReflectionPad3d(int((kernel_size-1)/2)) def forward(self, x): ftrs = [] - x = self.periodic_upsample(x) for i in range(len(self.channels)): ftrs.append(x) x =self.enc_blocks[i](x) diff --git a/UNet/UNet_V11.py b/UNet/UNet_V11.py index 20bcbb73d7d9fdf12deca7ee88f7d1046bc69ec8..fc4d65a0021f0bdacf038f7e9d8e27cbf8bce994 100644 --- a/UNet/UNet_V11.py +++ b/UNet/UNet_V11.py @@ -54,18 +54,16 @@ class head_layer(nn.Module): #return self.sig(self.pointwise(self.depthwise(x))) #convolution class Encoder(nn.Module): - def __init__(self,kernel_size, chs, padding=((0,"same"),("same","same"),("same","same"))): + def __init__(self,kernel_size, chs, padding=(("same","same"),("same","same"),("same","same"))): super().__init__() self.channels = chs self.enc_blocks = nn.ModuleList([depthwise_separable_conv(chs[i][0], chs[i][1], chs[i][2], kernel_size=kernel_size, padding=padding[i]) for i in range(len(chs))]) self.pool = nn.MaxPool3d(kernel_size=2, stride=2) #self.batch_norm = nn.ModuleList([nn.BatchNorm3d( chs[i][2]) for i in range(len(chs))]) - self.periodic_upsample = nn.ReflectionPad3d(int((kernel_size-1)/2)) def forward(self, x): ftrs = [] - x = self.periodic_upsample(x) for i in range(len(self.channels)): ftrs.append(x) x =self.enc_blocks[i](x) diff --git a/UNet/UNet_V12.py b/UNet/UNet_V12.py index 122915551774b1c8662f3f27e66a485ec1024e96..64cdae4f106749bbf38403c47201b4a33a604345 100644 --- a/UNet/UNet_V12.py +++ b/UNet/UNet_V12.py @@ -51,18 +51,16 @@ class head_layer(nn.Module): #return self.sig(self.pointwise(self.depthwise(x))) #convolution class Encoder(nn.Module): - def __init__(self,kernel_size, chs, padding=((0,"same"),("same","same"),("same","same"))): + def __init__(self,kernel_size, chs, padding=(("same","same"),("same","same"),("same","same"))): super().__init__() self.channels = chs self.enc_blocks = nn.ModuleList([depthwise_separable_conv(chs[i][0], chs[i][1], chs[i][2], kernel_size=kernel_size, padding=padding[i]) for i in range(len(chs))]) self.pool = nn.MaxPool3d(kernel_size=2, stride=2) #self.batch_norm = nn.ModuleList([nn.BatchNorm3d( chs[i][2]) for i in range(len(chs))]) - self.periodic_upsample = nn.ReflectionPad3d(int((kernel_size-1)/2)) def forward(self, x): ftrs = [] - x = self.periodic_upsample(x) for i in range(len(self.channels)): ftrs.append(x) x =self.enc_blocks[i](x) diff --git a/UNet/UNet_V13.py b/UNet/UNet_V13.py index 9e961c38534944e82f011f6fe4003d7e10d67f2b..2fae4d2fc76a42d747fd55dd92a95f67ea8fcab8 100644 --- a/UNet/UNet_V13.py +++ b/UNet/UNet_V13.py @@ -51,18 +51,16 @@ class head_layer(nn.Module): #return self.sig(self.pointwise(self.depthwise(x))) #convolution class Encoder(nn.Module): - def __init__(self,kernel_size, chs, padding=((0,"same"),("same","same"),("same","same"),("same","same"))): + def __init__(self,kernel_size, chs, padding=(("same","same"),("same","same"),("same","same"),("same","same"))): super().__init__() self.channels = chs self.enc_blocks = nn.ModuleList([depthwise_separable_conv(chs[i][0], chs[i][1], chs[i][2], kernel_size=kernel_size, padding=padding[i]) for i in range(len(chs))]) self.pool = nn.MaxPool3d(kernel_size=2, stride=2) #self.batch_norm = nn.ModuleList([nn.BatchNorm3d( chs[i][2]) for i in range(len(chs))]) - self.periodic_upsample = nn.ReflectionPad3d(int((kernel_size-1)/2)) def forward(self, x): ftrs = [] - x = self.periodic_upsample(x) for i in range(len(self.channels)): ftrs.append(x) x =self.enc_blocks[i](x) diff --git a/UNet/UNet_V14.py b/UNet/UNet_V14.py index e32d3668177d6adaa1dbe0ed6e456d276aba02d0..9863c1f6d7455a6cff55d010622e18a24ed32d9b 100644 --- a/UNet/UNet_V14.py +++ b/UNet/UNet_V14.py @@ -50,18 +50,16 @@ class head_layer(nn.Module): #return self.sig(self.pointwise(self.depthwise(x))) #convolution class Encoder(nn.Module): - def __init__(self,kernel_size, chs, padding=(0,"same","same","same")): + def __init__(self,kernel_size, chs, padding=("same","same","same","same")): super().__init__() self.channels = chs self.enc_blocks = nn.ModuleList([depthwise_separable_conv(chs[i][0], chs[i][1],kernel_size=kernel_size, padding=padding[i]) for i in range(len(chs))]) self.pool = nn.MaxPool3d(kernel_size=2, stride=2) #self.batch_norm = nn.ModuleList([nn.BatchNorm3d( chs[i][2]) for i in range(len(chs))]) - self.periodic_upsample = nn.ReflectionPad3d(int((kernel_size-1)/2)) def forward(self, x): ftrs = [] - x = self.periodic_upsample(x) for i in range(len(self.channels)): ftrs.append(x) x =self.enc_blocks[i](x) diff --git a/UNet/UNet_V15.py b/UNet/UNet_V15.py new file mode 100644 index 0000000000000000000000000000000000000000..b20f5ecfa19e3d9908cf4edafcd2e37f47e3d027 --- /dev/null +++ b/UNet/UNet_V15.py @@ -0,0 +1,252 @@ +#like V6_2 but only the different phases as input +"""UNet_V6.ipynb + +Automatically generated by Colaboratory. + +Original file is located at + https://colab.research.google.com/drive/1yvtk3lFo_x0ZiqtFdnR8jgcjPKy3nZA4 +""" + +import torch +import torch.nn as nn +import numpy as np +import random +from torch.utils.data.sampler import SubsetRandomSampler +from torch.utils.data.dataloader import DataLoader +from torch.utils.data import TensorDataset +import torch.nn.functional as F +from torch.utils.data import random_split +from torch.nn.modules.activation import ReLU + +class depthwise_separable_conv(nn.Module): + def __init__(self, in_c, out_1_c, out_2_c, padding, kernel_size): + super(depthwise_separable_conv, self).__init__() + self.depthwise_1 = nn.Conv3d(in_c, in_c, kernel_size= kernel_size, padding=padding[0], groups=in_c, bias=True) + self.pointwise_1 = nn.Conv3d(in_c, out_1_c, kernel_size=1, bias=True) + self.batch_norm_1 = nn.BatchNorm3d(out_1_c) + self.relu = nn.ReLU() + self.droptout = nn.Dropout3d(p=0.25) + self.depthwise_2 = nn.Conv3d(out_1_c, out_1_c, kernel_size= kernel_size, padding=padding[1], groups=out_1_c, bias=True) + self.pointwise_2 = nn.Conv3d(out_1_c, out_2_c, kernel_size=1, bias=True) + self.batch_norm_2 = nn.BatchNorm3d(out_2_c) + def forward(self, x): + x = self.batch_norm_1(self.relu(self.droptout(self.pointwise_1(self.depthwise_1(x))))) + return self.batch_norm_2(self.relu(self.droptout(self.pointwise_2(self.depthwise_2(x))))) + +class convolution_Layer(nn.Module): + def __init__(self, in_c, out_1_c, out_2_c, padding, kernel_size): + super(convolution_Layer, self).__init__() + self.conv_1 = nn.Conv3d(in_c, out_1_c, kernel_size= kernel_size, padding=padding[0], bias=True) + self.batch_norm_1 = nn.BatchNorm3d(out_1_c) + self.relu = nn.ReLU() + self.conv_2 = nn.Conv3d(out_1_c, out_2_c, kernel_size= kernel_size, padding=padding[1], bias=True) + self.batch_norm_2 = nn.BatchNorm3d(out_2_c) + def forward(self, x): + x = self.batch_norm_1(self.relu(self.conv_1(x))) + return self.batch_norm_2(self.relu(self.relu(self.conv_2(x)))) + +class head_layer(nn.Module): + def __init__(self, in_c, out_c = 1, padding = "same"): + super(head_layer, self).__init__() + self.conv = nn.Conv3d(in_c, out_c, kernel_size=1, bias=True) + self.sig = nn.Sigmoid() + def forward(self, x): + return self.sig(self.conv(x)) #convolution + #return self.sig(self.pointwise(self.depthwise(x))) #convolution + +class Encoder(nn.Module): + def __init__(self,kernel_size, chs, padding=(("same","same"),("same","same"),("same","same"))): + super().__init__() + self.channels = chs + self.enc_blocks = nn.ModuleList([depthwise_separable_conv(chs[i][0], chs[i][1], chs[i][2], kernel_size=kernel_size, padding=padding[i]) for i in range(len(chs))]) + self.pool = nn.MaxPool3d(kernel_size=2, stride=2) + #self.batch_norm = nn.ModuleList([nn.BatchNorm3d( chs[i][2]) for i in range(len(chs))]) + + + def forward(self, x): + ftrs = [] + for i in range(len(self.channels)): + ftrs.append(x) + x =self.enc_blocks[i](x) + #print(f'size of ftrs: {ftrs[i].size()}') + x = self.pool(x) + #print(f'size of x after pooling{x.size()}') + ftrs.append(x) + #print(f'size of ftrs: {ftrs[3].size()}') + #print(f'length of ftrs: {len(ftrs)}') + return ftrs + +class Decoder(nn.Module): + def __init__(self,kernel_size, chs_upsampling, chs_conv, padding=(("same","same"),("same","same"),("same","same"))): + super().__init__() + assert len(chs_conv) == len(chs_upsampling) + self.chs = chs_upsampling + self.upconvs = nn.ModuleList([nn.ConvTranspose3d(chs_upsampling[i], chs_upsampling[i], 2, 2) for i in range(len(chs_upsampling))]) + self.dec_blocks = nn.ModuleList([depthwise_separable_conv(chs_conv[i][0], chs_conv[i][1], chs_conv[i][2], kernel_size=kernel_size, padding=padding[i]) for i in range(len(chs_conv))]) + self.head = head_layer(chs_conv[-1][2]) + def forward(self, x, encoder_features): + for i in range(len(self.chs)): + x = self.upconvs[i](x) + #print(f'size after upsampling: {x.size()}') + enc_ftrs = self.crop(encoder_features[i], x) + x = torch.cat([x, enc_ftrs], dim=1) + #print(f'size after cropping&cat: {x.size()}') + + x = self.dec_blocks[i](x) + #print(f'size after convolution: {x.size()}') + x = self.head(x) + return x + + def crop(self, tensor, target_tensor): + target_size = target_tensor.size()[2] + tensor_size = tensor.size()[2] + delta = tensor_size - target_size + delta = delta // 2 + return tensor[:,:,delta:tensor_size-delta,delta:tensor_size-delta,delta:tensor_size-delta] + +class UNetBase(nn.Module): + def training_step(self, batch): + input, labels = batch + out = self(input) # Generate predictions + loss = F.l1_loss(out, labels) # Calculate loss + return loss + + def validation_step(self, batch): + input, labels = batch + out = self(input) # Generate predictions + loss = F.l1_loss(out, labels) # Calculate loss + acc = accuracy(out.detach(), labels.detach(),normalization=self.normalization) # Calculate accuracy + return {'val_loss': loss.detach(), 'val_acc': acc} + + def validation_epoch_end(self, outputs): + batch_losses = [x['val_loss'] for x in outputs] + epoch_loss = torch.stack(batch_losses).mean() # Combine losses + batch_accs = [x['val_acc'] for x in outputs] + epoch_acc = torch.stack(batch_accs).mean() # Combine accuracies + return {'val_loss': epoch_loss.item(), 'val_acc': epoch_acc.item()} + + def epoch_end(self, epoch, result): + print("Epoch [{}], train_loss: {:.6f}, val_loss: {:.6f}, val_acc: {:.6f}".format( + epoch, result['train_loss'], result['val_loss'], result['val_acc'])) + +def accuracy(outputs, labels,normalization, threshold = 0.05): + error = (abs((outputs) - (labels)))/(outputs+normalization[0]/normalization[1]) + right_predic = torch.sum(error < threshold) + percentage = ((right_predic/torch.numel(error))*100.) + return percentage + +class UNet(UNetBase): + def __init__(self,kernel_size = 7, enc_chs=((2,16,32), (32,32,64), (64,64,128)), dec_chs_up=(128, 128, 64), dec_chs_conv=((192,128, 128),(160,64,64),(66,32,32)),normalization=np.array([0,1])): + super().__init__() + self.encoder = Encoder(kernel_size = kernel_size, chs = enc_chs) + self.decoder = Decoder(kernel_size = kernel_size, chs_upsampling = dec_chs_up, chs_conv = dec_chs_conv) + #self.head = depthwise_separable_conv(1, 1, padding = "same", kernel_size=1) + self.normalization = normalization + + + def forward(self, x): + enc_ftrs = self.encoder(x) + out = self.decoder(enc_ftrs[::-1][0], enc_ftrs[::-1][1:]) + #out = self.head(out) + return out + +@torch.no_grad() +def evaluate(model, val_loader): + model.eval() + outputs = [model.validation_step(batch) for batch in val_loader] + return model.validation_epoch_end(outputs) + +def fit(epochs, lr, model, train_loader, val_loader, path, opt_func=torch.optim.Adam): + history = [] + optimizer = opt_func(model.parameters(), lr, eps=1e-07) + for epoch in range(epochs): + # Training Phase + model.train() + train_losses = [] + for batch in train_loader: + loss = model.training_step(batch) + train_losses.append(loss) + loss.backward() + optimizer.step() + optimizer.zero_grad() + # Validation phase + result = evaluate(model, val_loader) + result['train_loss'] = torch.stack(train_losses).mean().item() + model.epoch_end(epoch, result) + history.append(result) + torch.save(model.state_dict(),f'{path}/Unet_dict_V15.pth') + torch.save(history,f'{path}/history_V15.pt') + return history + +def get_default_device(): + """Pick GPU if available, else CPU""" + if torch.cuda.is_available(): + return torch.device('cuda') + else: + print('no GPU found') + return torch.device('cpu') + +def to_device(data, device): + """Move tensor(s) to chosen device""" + if isinstance(data, (list,tuple)): + return [to_device(x, device) for x in data] + return data.to(device, non_blocking=True) + +class DeviceDataLoader(): + """Wrap a dataloader to move data to a device""" + def __init__(self, dl, device): + self.dl = dl + self.device = device + + def __iter__(self): + """Yield a batch of data after moving it to device""" + for b in self.dl: + yield to_device(b, self.device) + + def __len__(self): + """Number of batches""" + return len(self.dl) + +def Create_Dataloader(path, batch_size = 100, percent_val = 0.2): + dataset = torch.load(path) # create the pytorch dataset + #size_data = 500 #shrink dataset for colab + #rest = len(dataset) -size_data + #dataset,_ = torch.utils.data.random_split(dataset, [size_data, rest]) + val_size = int(len(dataset) * percent_val) + train_size = len(dataset) - val_size + + train_ds, val_ds = random_split(dataset, [train_size, val_size]) + # Create DataLoader + train_dl = DataLoader(train_ds, batch_size, shuffle=True, num_workers=1, pin_memory=True) + valid_dl = DataLoader(val_ds, batch_size, num_workers=1, pin_memory=True) + + return train_dl, valid_dl + +if __name__ == '__main__': + #os.chdir('F:/RWTH/HiWi_IEHK/DAMASK3/UNet/Trainingsdata') + path_to_rep = '/home/yk138599/Hiwi/damask3' + use_seeds = False + seed = 373686838 + num_epochs = 1000 + b_size = 32 + opt_func = torch.optim.Adam + lr = 0.00003 + kernel = 7 + print(f'number auf epochs: {num_epochs}') + print(f'batchsize: {b_size}') + print(f'learning rate: {lr}') + print(f'kernel size is: {kernel}') + if not use_seeds: + seed = random.randrange(2**32 - 1) + print(f' seed is: {seed}') + torch.manual_seed(seed) + random.seed(seed) + np.random.seed(seed) + device = get_default_device() + normalization = np.load(f'{path_to_rep}/UNet/Trainingsdata/Norm_min_max_32_phase_only.npy', allow_pickle = True) + train_dl, valid_dl = Create_Dataloader(f'{path_to_rep}/UNet/Trainingsdata/TD_norm_32_phase_only.pt', batch_size= b_size ) + train_dl = DeviceDataLoader(train_dl, device) + valid_dl = DeviceDataLoader(valid_dl, device) + + model = to_device(UNet(kernel_size=kernel,normalization=normalization).double(), device) + history = fit(num_epochs, lr, model, train_dl, valid_dl,f'{path_to_rep}/UNet/output', opt_func) diff --git a/UNet/UNet_V16.py b/UNet/UNet_V16.py new file mode 100644 index 0000000000000000000000000000000000000000..32797637d7079c328c0bfed76ec7a3fa3b9c8f11 --- /dev/null +++ b/UNet/UNet_V16.py @@ -0,0 +1,253 @@ + +"""UNet_V6.ipynb + +Automatically generated by Colaboratory. + +Original file is located at + https://colab.research.google.com/drive/1yvtk3lFo_x0ZiqtFdnR8jgcjPKy3nZA4 +""" + +import torch +import torch.nn as nn +import numpy as np +import random +from torch.utils.data.sampler import SubsetRandomSampler +from torch.utils.data.dataloader import DataLoader +from torch.utils.data import TensorDataset +import torch.nn.functional as F +from torch.utils.data import random_split +from torch.nn.modules.activation import ReLU + +class depthwise_separable_conv(nn.Module): + def __init__(self, in_c, out_1_c, out_2_c, padding, kernel_size): + super(depthwise_separable_conv, self).__init__() + self.depthwise_1 = nn.Conv3d(in_c, in_c, kernel_size= kernel_size, padding=padding[0], groups=in_c, bias=True) + self.pointwise_1 = nn.Conv3d(in_c, out_1_c, kernel_size=1, bias=True) + self.batch_norm_1 = nn.BatchNorm3d(out_1_c) + self.relu = nn.ReLU() + self.droptout = nn.Dropout3d(p=0.5) + + self.depthwise_2 = nn.Conv3d(out_1_c, out_1_c, kernel_size= kernel_size, padding=padding[1], groups=out_1_c, bias=True) + self.pointwise_2 = nn.Conv3d(out_1_c, out_2_c, kernel_size=1, bias=True) + self.batch_norm_2 = nn.BatchNorm3d(out_2_c) + def forward(self, x): + x = self.batch_norm_1(self.relu(self.droptout(self.pointwise_1(self.depthwise_1(x))))) + return self.batch_norm_2(self.relu(self.droptout(self.pointwise_2(self.depthwise_2(x))))) + +class convolution_Layer(nn.Module): + def __init__(self, in_c, out_1_c, out_2_c, padding, kernel_size): + super(convolution_Layer, self).__init__() + self.conv_1 = nn.Conv3d(in_c, out_1_c, kernel_size= kernel_size, padding=padding[0], bias=True) + self.batch_norm_1 = nn.BatchNorm3d(out_1_c) + self.relu = nn.ReLU() + self.conv_2 = nn.Conv3d(out_1_c, out_2_c, kernel_size= kernel_size, padding=padding[1], bias=True) + self.batch_norm_2 = nn.BatchNorm3d(out_2_c) + def forward(self, x): + x = self.batch_norm_1(self.relu(self.conv_1(x))) + return self.batch_norm_2(self.relu(self.relu(self.conv_2(x)))) + +class head_layer(nn.Module): + def __init__(self, in_c, out_c = 1, padding = "same"): + super(head_layer, self).__init__() + self.conv = nn.Conv3d(in_c, out_c, kernel_size=1, bias=True) + self.sig = nn.Sigmoid() + def forward(self, x): + return self.sig(self.conv(x)) #convolution + #return self.sig(self.pointwise(self.depthwise(x))) #convolution + +class Encoder(nn.Module): + def __init__(self,kernel_size, chs, padding=(("same","same"),("same","same"),("same","same"))): + super().__init__() + self.channels = chs + self.enc_blocks = nn.ModuleList([depthwise_separable_conv(chs[i][0], chs[i][1], chs[i][2], kernel_size=kernel_size, padding=padding[i]) for i in range(len(chs))]) + self.pool = nn.MaxPool3d(kernel_size=2, stride=2) + #self.batch_norm = nn.ModuleList([nn.BatchNorm3d( chs[i][2]) for i in range(len(chs))]) + + + def forward(self, x): + ftrs = [] + for i in range(len(self.channels)): + ftrs.append(x) + x =self.enc_blocks[i](x) + #print(f'size of ftrs: {ftrs[i].size()}') + x = self.pool(x) + #print(f'size of x after pooling{x.size()}') + ftrs.append(x) + #print(f'size of ftrs: {ftrs[3].size()}') + #print(f'length of ftrs: {len(ftrs)}') + return ftrs + +class Decoder(nn.Module): + def __init__(self,kernel_size, chs_upsampling, chs_conv, padding=(("same","same"),("same","same"),("same","same"))): + super().__init__() + assert len(chs_conv) == len(chs_upsampling) + self.chs = chs_upsampling + self.upconvs = nn.ModuleList([nn.ConvTranspose3d(chs_upsampling[i], chs_upsampling[i], 2, 2) for i in range(len(chs_upsampling))]) + self.dec_blocks = nn.ModuleList([depthwise_separable_conv(chs_conv[i][0], chs_conv[i][1], chs_conv[i][2], kernel_size=kernel_size, padding=padding[i]) for i in range(len(chs_conv))]) + self.head = head_layer(chs_conv[-1][2]) + def forward(self, x, encoder_features): + for i in range(len(self.chs)): + x = self.upconvs[i](x) + #print(f'size after upsampling: {x.size()}') + enc_ftrs = self.crop(encoder_features[i], x) + x = torch.cat([x, enc_ftrs], dim=1) + #print(f'size after cropping&cat: {x.size()}') + + x = self.dec_blocks[i](x) + #print(f'size after convolution: {x.size()}') + x = self.head(x) + return x + + def crop(self, tensor, target_tensor): + target_size = target_tensor.size()[2] + tensor_size = tensor.size()[2] + delta = tensor_size - target_size + delta = delta // 2 + return tensor[:,:,delta:tensor_size-delta,delta:tensor_size-delta,delta:tensor_size-delta] + +class UNetBase(nn.Module): + def training_step(self, batch): + input, labels = batch + out = self(input) # Generate predictions + loss = F.l1_loss(out, labels) # Calculate loss + return loss + + def validation_step(self, batch): + input, labels = batch + out = self(input) # Generate predictions + loss = F.l1_loss(out, labels) # Calculate loss + acc = accuracy(out.detach(), labels.detach(),normalization=self.normalization) # Calculate accuracy + return {'val_loss': loss.detach(), 'val_acc': acc} + + def validation_epoch_end(self, outputs): + batch_losses = [x['val_loss'] for x in outputs] + epoch_loss = torch.stack(batch_losses).mean() # Combine losses + batch_accs = [x['val_acc'] for x in outputs] + epoch_acc = torch.stack(batch_accs).mean() # Combine accuracies + return {'val_loss': epoch_loss.item(), 'val_acc': epoch_acc.item()} + + def epoch_end(self, epoch, result): + print("Epoch [{}], train_loss: {:.6f}, val_loss: {:.6f}, val_acc: {:.6f}".format( + epoch, result['train_loss'], result['val_loss'], result['val_acc'])) + +def accuracy(outputs, labels,normalization, threshold = 0.05): + error = (abs((outputs) - (labels)))/(outputs+normalization[0]/normalization[1]) + right_predic = torch.sum(error < threshold) + percentage = ((right_predic/torch.numel(error))*100.) + return percentage + +class UNet(UNetBase): + def __init__(self,kernel_size = 7, enc_chs=((6,16,32), (32,32,64), (64,64,128)), dec_chs_up=(128, 128, 64), dec_chs_conv=((192,128, 128),(160,64,64),(70,32,32)),normalization=np.array([0,1])): + super().__init__() + self.encoder = Encoder(kernel_size = kernel_size, chs = enc_chs) + self.decoder = Decoder(kernel_size = kernel_size, chs_upsampling = dec_chs_up, chs_conv = dec_chs_conv) + #self.head = depthwise_separable_conv(1, 1, padding = "same", kernel_size=1) + self.normalization = normalization + + + def forward(self, x): + enc_ftrs = self.encoder(x) + out = self.decoder(enc_ftrs[::-1][0], enc_ftrs[::-1][1:]) + #out = self.head(out) + return out + +@torch.no_grad() +def evaluate(model, val_loader): + model.eval() + outputs = [model.validation_step(batch) for batch in val_loader] + return model.validation_epoch_end(outputs) + +def fit(epochs, lr, model, train_loader, val_loader, path, opt_func=torch.optim.Adam): + history = [] + optimizer = opt_func(model.parameters(), lr, eps=1e-07) + for epoch in range(epochs): + # Training Phase + model.train() + train_losses = [] + for batch in train_loader: + loss = model.training_step(batch) + train_losses.append(loss) + loss.backward() + optimizer.step() + optimizer.zero_grad() + # Validation phase + result = evaluate(model, val_loader) + result['train_loss'] = torch.stack(train_losses).mean().item() + model.epoch_end(epoch, result) + history.append(result) + torch.save(model.state_dict(),f'{path}/Unet_dict_V11.pth') + torch.save(history,f'{path}/history_V11.pt') + return history + +def get_default_device(): + """Pick GPU if available, else CPU""" + if torch.cuda.is_available(): + return torch.device('cuda') + else: + print('no GPU found') + return torch.device('cpu') + +def to_device(data, device): + """Move tensor(s) to chosen device""" + if isinstance(data, (list,tuple)): + return [to_device(x, device) for x in data] + return data.to(device, non_blocking=True) + +class DeviceDataLoader(): + """Wrap a dataloader to move data to a device""" + def __init__(self, dl, device): + self.dl = dl + self.device = device + + def __iter__(self): + """Yield a batch of data after moving it to device""" + for b in self.dl: + yield to_device(b, self.device) + + def __len__(self): + """Number of batches""" + return len(self.dl) + +def Create_Dataloader(path, batch_size = 100, percent_val = 0.2): + dataset = torch.load(path) # create the pytorch dataset + #size_data = 500 #shrink dataset for colab + #rest = len(dataset) -size_data + #dataset,_ = torch.utils.data.random_split(dataset, [size_data, rest]) + val_size = int(len(dataset) * percent_val) + train_size = len(dataset) - val_size + + train_ds, val_ds = random_split(dataset, [train_size, val_size]) + # Create DataLoader + train_dl = DataLoader(train_ds, batch_size, shuffle=True, num_workers=1, pin_memory=True) + valid_dl = DataLoader(val_ds, batch_size, num_workers=1, pin_memory=True) + + return train_dl, valid_dl + +if __name__ == '__main__': + #os.chdir('F:/RWTH/HiWi_IEHK/DAMASK3/UNet/Trainingsdata') + path_to_rep = '/home/yk138599/Hiwi/damask3' + use_seeds = True + seed = 373686838 + num_epochs = 10000 + b_size = 32 + opt_func = torch.optim.Adam + lr = 0.00003 + kernel = 7 + print(f'number auf epochs: {num_epochs}') + print(f'batchsize: {b_size}') + print(f'learning rate: {lr}') + print(f'kernel size is: {kernel}') + if not use_seeds: + seed = random.randrange(2**32 - 1) + print(f' seed is: {seed}') + torch.manual_seed(seed) + random.seed(seed) + np.random.seed(seed) + device = get_default_device() + normalization = np.load(f'{path_to_rep}/UNet/Trainingsdata/Norm_min_max_32_angles.npy', allow_pickle = True) + train_dl, valid_dl = Create_Dataloader(f'{path_to_rep}/UNet/Trainingsdata/TD_norm_32_angles.pt', batch_size= b_size ) + train_dl = DeviceDataLoader(train_dl, device) + valid_dl = DeviceDataLoader(valid_dl, device) + + model = to_device(UNet(kernel_size=kernel,normalization=normalization).double(), device) + history = fit(num_epochs, lr, model, train_dl, valid_dl,f'{path_to_rep}/UNet/output', opt_func) diff --git a/UNet/UNet_V9_2.py b/UNet/UNet_V9_2.py index f837a3632047a3e445d5874b531fdbf97153dcf7..f5c5bd9068e06aa7f025bcf6b04e485d66a91318 100644 --- a/UNet/UNet_V9_2.py +++ b/UNet/UNet_V9_2.py @@ -54,18 +54,16 @@ class head_layer(nn.Module): #return self.sig(self.pointwise(self.depthwise(x))) #convolution class Encoder(nn.Module): - def __init__(self,kernel_size, chs, padding=((0,"same"),("same","same"),("same","same"))): + def __init__(self,kernel_size, chs, padding=(("same","same"),("same","same"),("same","same"))): super().__init__() self.channels = chs self.enc_blocks = nn.ModuleList([depthwise_separable_conv(chs[i][0], chs[i][1], chs[i][2], kernel_size=kernel_size, padding=padding[i]) for i in range(len(chs))]) self.pool = nn.MaxPool3d(kernel_size=2, stride=2) #self.batch_norm = nn.ModuleList([nn.BatchNorm3d( chs[i][2]) for i in range(len(chs))]) - self.periodic_upsample = nn.ReflectionPad3d(int((kernel_size-1)/2)) def forward(self, x): ftrs = [] - x = self.periodic_upsample(x) for i in range(len(self.channels)): ftrs.append(x) x =self.enc_blocks[i](x) diff --git a/UNet/UNet_V9_3.py b/UNet/UNet_V9_3.py index 0c07f78b7f6f9fba88c465d079c53af0ec45360b..18068f80fb265d30bcf3d546786c38d73bfb48d6 100644 --- a/UNet/UNet_V9_3.py +++ b/UNet/UNet_V9_3.py @@ -54,18 +54,16 @@ class head_layer(nn.Module): #return self.sig(self.pointwise(self.depthwise(x))) #convolution class Encoder(nn.Module): - def __init__(self,kernel_size, chs, padding=((0,"same"),("same","same"),("same","same"))): + def __init__(self,kernel_size, chs, padding=(("same","same"),("same","same"),("same","same"))): super().__init__() self.channels = chs self.enc_blocks = nn.ModuleList([depthwise_separable_conv(chs[i][0], chs[i][1], chs[i][2], kernel_size=kernel_size, padding=padding[i]) for i in range(len(chs))]) self.pool = nn.MaxPool3d(kernel_size=2, stride=2) #self.batch_norm = nn.ModuleList([nn.BatchNorm3d( chs[i][2]) for i in range(len(chs))]) - self.periodic_upsample = nn.ReflectionPad3d(int((kernel_size-1)/2)) def forward(self, x): ftrs = [] - x = self.periodic_upsample(x) for i in range(len(self.channels)): ftrs.append(x) x =self.enc_blocks[i](x) diff --git a/UNet/postprocessing_new.ipynb b/UNet/postprocessing_new.ipynb index 0962e7bf1037c8b8cc7279a69b848479af928581..9fedc11e1f25ebd293f1629a054a76dc0ee7f31e 100644 --- a/UNet/postprocessing_new.ipynb +++ b/UNet/postprocessing_new.ipynb @@ -2,14 +2,14 @@ "cells": [ { "cell_type": "code", - "execution_count": 14, + "execution_count": 1, "metadata": {}, "outputs": [], "source": [ "import torch\n", "import numpy as np\n", "import matplotlib.pyplot as plt\n", - "import UNet_V11 as UNet\n", + "import UNet_V15 as UNet\n", "import pyvista as pv\n", "from matplotlib.colors import ListedColormap\n", "import copy\n", @@ -19,7 +19,7 @@ }, { "cell_type": "code", - "execution_count": 21, + "execution_count": 3, "metadata": {}, "outputs": [], "source": [ @@ -52,7 +52,7 @@ "def rescale(output, normalization):\n", " output_rescale = output.reshape(output.shape[2],output.shape[3],output.shape[4])\n", " if normalization is not None:\n", - " min_label, max_label,_ = normalization\n", + " min_label, max_label = normalization\n", " output_rescale *= max_label.numpy()\n", " output_rescale += min_label.numpy()\n", " return output_rescale\n", @@ -117,7 +117,7 @@ }, { "cell_type": "code", - "execution_count": 11, + "execution_count": 4, "metadata": {}, "outputs": [], "source": [ @@ -177,7 +177,7 @@ }, { "cell_type": "code", - "execution_count": 15, + "execution_count": 5, "metadata": {}, "outputs": [ { @@ -189,39 +189,62 @@ } ], "source": [ - "Training_data = torch.load('E:/Data/damask3/UNet/Input/TD_norm_32_angles.pt')\n", - "grain_data = torch.load('E:/Data/damask3/UNet/Input/TD_norm_32_angles.pt')\n", - "#history = torch.load('E:/Data/damask3/UNet/output/V6_64/history_V6_2_64.pt')\n", + "Training_data = torch.load('F:/RWTH/HiWi_IEHK/DAMASK3/UNet/Trainingsdata/TD_norm_32_phase.pt')\n", + "grain_data = torch.load('F:/RWTH/HiWi_IEHK/DAMASK3/UNet/Trainingsdata/TD_norm_32_phase.pt')\n", + "history = torch.load('F:/RWTH/HiWi_IEHK/DAMASK3/UNet/output/V15/history_V15.pt')\n", "#history_2 = torch.load('E:/Data/damask3/UNet/output/history_test.pt')\n", - "normalization = np.load('E:/Data/damask3/UNet/Input/Norm_min_max_32_angles.npy', allow_pickle=True)\n", + "normalization = np.load('F:/RWTH/HiWi_IEHK/DAMASK3/UNet/Trainingsdata/Norm_min_max_32_phase.npy', allow_pickle=True)\n", "model = UNet.UNet()\n", - "model.load_state_dict(torch.load('E:/Data/damask3/UNet/output/V11/Unet_dict_V11.pth',map_location=torch.device('cpu')))\n", + "model.load_state_dict(torch.load('F:/RWTH/HiWi_IEHK/DAMASK3/UNet/output/V15/Unet_dict_V15.pth',map_location=torch.device('cpu')))\n", "device = UNet.get_default_device()\n", "model = UNet.to_device(model.double(), device)" ] }, { "cell_type": "code", - "execution_count": null, + "execution_count": 6, "metadata": {}, - "outputs": [], + "outputs": [ + { + "data": { + "image/png": "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36OPPkpaWhqBQIDx48ezbNkybrrpJp566ilmzZpF8+ZVZwRZtGgRb775JvPnz6+Ya2/MmDGkpqayevVq3nvvPV599VXOPfdcPvnkEy688MIa7+/iiy/mueeeY8yYMdx///089NBDTJ06Fbfbzfr164mJialoVnziiSd44YUXGDlyJPn5+cSG1pkTkZEl32tR3gcVLKl9PZa9lZQFKl7/MqX6lViFOFINGDCAHTt2sGXLFpYuXUpqaiodOnTAMAzuvvtu+vbty3HHHcfmzZvZvn17jeeZO3duRaDo27cvffv2rdj34YcfMnDgQAYMGMCKFStYubL2J01++eUXzjjjDBISEkhMTOTMM8/k559/BqBz5870798fgEGDBuHz+Wo8T25uLjk5OYwZMwaASy65hLlz51aU8YILLuCdd96hvN975MiR3HrrrTz77LPk5ORQ3/7wpkrerVqoGLPfySitWw2qRVIMBVmF/DJlnDyMKg6p2mo6Demcc87h448/Ztu2bUyaNAmA6dOnk5mZyaJFi7DZbNjtdoqLi+t87vXr1/PEE0+Yk8SmpnLppZfW6zzlKk8ga7Vawzbx1cTj8TB37ly++uorHn30UZYvX47L5cLpdDJz5kxGjhzJt99+i8Mhj3RESmpQtahPH1RWfgm+rELuPtkhwUk0WZMmTeL999/n448/5pxzzNb63NxcWrZsic1mY9asWWzYsKHWcxxzzDG8++67APz1118sW7YMgN27d5OQkECzZs3Yvn07X3/9dcUxSUlJ1fbzjB49ms8//5zCwkIKCgr47LPPGD267iv3NmvWjNTU1Ira19tvv82YMWMIBoNs2rSJcePG8dhjj5Gbm0t+fj5r166lT58+TJkyhSFDhuD1Htjm1iOd1KBqUd4HFSyOPED5ssw5/7q1lEEQounq1asXeXl5tGvXjjZtzGf7LrjgAk455RT69OnD4MGDw9Ykrr32Wi677DI0TUPTNAYNGgRAv379GDBgAA6Hgw4dOjBy5MiKY6666ipOPPFE2rZty6xZsyrSBw4cyKWXXsrQoUMBczmNAQMG1NqcV5O33nqLa665hsLCQrp06cKbb75JIBDgwgsvJDc3F8MwuOmmm0hJSeG+++5j1qxZWCwWevXqxUknnVTn6zVlMpt5LYpXrWL9aafTburTJJ94YkTHfLwog9s/WsqPt42h6wFc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", + "text/plain": [ + "<Figure size 432x288 with 2 Axes>" + ] + }, + "metadata": { + "needs_background": "light" + }, + "output_type": "display_data" + } + ], "source": [ "plot_losses(history)" ] }, { "cell_type": "code", - "execution_count": 22, + "execution_count": 7, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ - "sample number: 257\n", - "Maximum error is : 87.92 %\n", - "average error is : 12.27 %\n", - "48.08% of voxels have a diviation less than 10.0%\n" + "sample number: 694\n" + ] + }, + { + "ename": "ValueError", + "evalue": "not enough values to unpack (expected 3, got 2)", + "output_type": "error", + "traceback": [ + "\u001b[1;31m---------------------------------------------------------------------------\u001b[0m", + "\u001b[1;31mValueError\u001b[0m Traceback (most recent call last)", + "\u001b[1;32mC:\\Users\\CHRIST~1\\AppData\\Local\\Temp/ipykernel_14232/2407959253.py\u001b[0m in \u001b[0;36m<module>\u001b[1;34m\u001b[0m\n\u001b[0;32m 1\u001b[0m \u001b[0msample_index\u001b[0m \u001b[1;33m=\u001b[0m \u001b[0mnp\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mrandom\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mrandint\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mlow\u001b[0m\u001b[1;33m=\u001b[0m\u001b[1;36m0\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mhigh\u001b[0m\u001b[1;33m=\u001b[0m\u001b[0mlen\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mTraining_data\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 2\u001b[0m \u001b[0mprint\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;34mf'sample number: {sample_index}'\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m----> 3\u001b[1;33m \u001b[0mpredict_stress\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0msample_index\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mnormalization\u001b[0m \u001b[1;33m=\u001b[0m \u001b[0mnormalization\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mmodel\u001b[0m \u001b[1;33m=\u001b[0m \u001b[0mmodel\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mdataset\u001b[0m \u001b[1;33m=\u001b[0m \u001b[0mTraining_data\u001b[0m\u001b[1;33m,\u001b[0m\u001b[0mgrain_data\u001b[0m \u001b[1;33m=\u001b[0m\u001b[0mgrain_data\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m", + "\u001b[1;32mC:\\Users\\CHRIST~1\\AppData\\Local\\Temp/ipykernel_14232/3453320516.py\u001b[0m in \u001b[0;36mpredict_stress\u001b[1;34m(image_id, normalization, model, dataset, grain_data, threshold)\u001b[0m\n\u001b[0;32m 15\u001b[0m \u001b[0mprediction\u001b[0m \u001b[1;33m=\u001b[0m \u001b[0mprediction\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mdetach\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mnumpy\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 16\u001b[0m \u001b[0moutput\u001b[0m \u001b[1;33m=\u001b[0m \u001b[0moutput\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mdetach\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mnumpy\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m---> 17\u001b[1;33m \u001b[0mprediction\u001b[0m \u001b[1;33m=\u001b[0m \u001b[0mrescale\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mprediction\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mnormalization\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m\u001b[0;32m 18\u001b[0m \u001b[0moutput\u001b[0m \u001b[1;33m=\u001b[0m \u001b[0mrescale\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0moutput\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mnormalization\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 19\u001b[0m \u001b[0merror\u001b[0m \u001b[1;33m=\u001b[0m \u001b[1;33m(\u001b[0m\u001b[0mabs\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0moutput\u001b[0m \u001b[1;33m-\u001b[0m \u001b[0mprediction\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m/\u001b[0m\u001b[0moutput\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n", + "\u001b[1;32mC:\\Users\\CHRIST~1\\AppData\\Local\\Temp/ipykernel_14232/3453320516.py\u001b[0m in \u001b[0;36mrescale\u001b[1;34m(output, normalization)\u001b[0m\n\u001b[0;32m 28\u001b[0m \u001b[0moutput_rescale\u001b[0m \u001b[1;33m=\u001b[0m \u001b[0moutput\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mreshape\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0moutput\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mshape\u001b[0m\u001b[1;33m[\u001b[0m\u001b[1;36m2\u001b[0m\u001b[1;33m]\u001b[0m\u001b[1;33m,\u001b[0m\u001b[0moutput\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mshape\u001b[0m\u001b[1;33m[\u001b[0m\u001b[1;36m3\u001b[0m\u001b[1;33m]\u001b[0m\u001b[1;33m,\u001b[0m\u001b[0moutput\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mshape\u001b[0m\u001b[1;33m[\u001b[0m\u001b[1;36m4\u001b[0m\u001b[1;33m]\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 29\u001b[0m \u001b[1;32mif\u001b[0m \u001b[0mnormalization\u001b[0m \u001b[1;32mis\u001b[0m \u001b[1;32mnot\u001b[0m \u001b[1;32mNone\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m---> 30\u001b[1;33m \u001b[0mmin_label\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mmax_label\u001b[0m\u001b[1;33m,\u001b[0m\u001b[0m_\u001b[0m \u001b[1;33m=\u001b[0m \u001b[0mnormalization\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m\u001b[0;32m 31\u001b[0m \u001b[0moutput_rescale\u001b[0m \u001b[1;33m*=\u001b[0m \u001b[0mmax_label\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mnumpy\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 32\u001b[0m \u001b[0moutput_rescale\u001b[0m \u001b[1;33m+=\u001b[0m \u001b[0mmin_label\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mnumpy\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n", + "\u001b[1;31mValueError\u001b[0m: not enough values to unpack (expected 3, got 2)" ] } ], @@ -293,7 +316,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.9.5" + "version": "3.9.10" }, "orig_nbformat": 4 },