@@ -149,6 +149,7 @@ Example runner will download all the required files like training data and model | |||||
* [Object Detection](test/TensorFlowNET.Examples/ImageProcess/ObjectDetection.cs) | * [Object Detection](test/TensorFlowNET.Examples/ImageProcess/ObjectDetection.cs) | ||||
* [Text Classification](test/TensorFlowNET.Examples/TextProcess/BinaryTextClassification.cs) | * [Text Classification](test/TensorFlowNET.Examples/TextProcess/BinaryTextClassification.cs) | ||||
* [CNN Text Classification](test/TensorFlowNET.Examples/TextProcess/cnn_models/VdCnn.cs) | * [CNN Text Classification](test/TensorFlowNET.Examples/TextProcess/cnn_models/VdCnn.cs) | ||||
* [MNIST CNN](test/TensorFlowNET.Examples/ImageProcess/DigitRecognitionCNN.cs) | |||||
* [Named Entity Recognition](test/TensorFlowNET.Examples/TextProcess/NER) | * [Named Entity Recognition](test/TensorFlowNET.Examples/TextProcess/NER) | ||||
* [Transfer Learning for Image Classification in InceptionV3](test/TensorFlowNET.Examples/ImageProcess/RetrainImageClassifier.cs) | * [Transfer Learning for Image Classification in InceptionV3](test/TensorFlowNET.Examples/ImageProcess/RetrainImageClassifier.cs) | ||||
@@ -1,7 +1,7 @@ | |||||
| | ||||
Microsoft Visual Studio Solution File, Format Version 12.00 | Microsoft Visual Studio Solution File, Format Version 12.00 | ||||
# Visual Studio Version 16 | |||||
VisualStudioVersion = 16.0.29025.244 | |||||
# Visual Studio 15 | |||||
VisualStudioVersion = 15.0.28307.645 | |||||
MinimumVisualStudioVersion = 10.0.40219.1 | MinimumVisualStudioVersion = 10.0.40219.1 | ||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "TensorFlowNET.UnitTest", "test\TensorFlowNET.UnitTest\TensorFlowNET.UnitTest.csproj", "{029A8CF1-CF95-4DCB-98AA-9D3D96A83B3E}" | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "TensorFlowNET.UnitTest", "test\TensorFlowNET.UnitTest\TensorFlowNET.UnitTest.csproj", "{029A8CF1-CF95-4DCB-98AA-9D3D96A83B3E}" | ||||
EndProject | EndProject | ||||
@@ -17,6 +17,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Keras.UnitTest", "test\Kera | |||||
EndProject | EndProject | ||||
Project("{6EC3EE1D-3C4E-46DD-8F32-0CC8E7565705}") = "TensorFlowNET.Examples.FSharp", "test\TensorFlowNET.Examples.FSharp\TensorFlowNET.Examples.FSharp.fsproj", "{62BC3801-F0D3-44A9-A0AC-712F40C8F961}" | Project("{6EC3EE1D-3C4E-46DD-8F32-0CC8E7565705}") = "TensorFlowNET.Examples.FSharp", "test\TensorFlowNET.Examples.FSharp\TensorFlowNET.Examples.FSharp.fsproj", "{62BC3801-F0D3-44A9-A0AC-712F40C8F961}" | ||||
EndProject | EndProject | ||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TensorFlowNet.Benchmark", "src\TensorFlowNet.Benchmarks\TensorFlowNet.Benchmark.csproj", "{68861442-971A-4196-876E-C9330F0B3C54}" | |||||
EndProject | |||||
Global | Global | ||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution | GlobalSection(SolutionConfigurationPlatforms) = preSolution | ||||
Debug|Any CPU = Debug|Any CPU | Debug|Any CPU = Debug|Any CPU | ||||
@@ -51,6 +53,10 @@ Global | |||||
{62BC3801-F0D3-44A9-A0AC-712F40C8F961}.Debug|Any CPU.Build.0 = Debug|Any CPU | {62BC3801-F0D3-44A9-A0AC-712F40C8F961}.Debug|Any CPU.Build.0 = Debug|Any CPU | ||||
{62BC3801-F0D3-44A9-A0AC-712F40C8F961}.Release|Any CPU.ActiveCfg = Release|Any CPU | {62BC3801-F0D3-44A9-A0AC-712F40C8F961}.Release|Any CPU.ActiveCfg = Release|Any CPU | ||||
{62BC3801-F0D3-44A9-A0AC-712F40C8F961}.Release|Any CPU.Build.0 = Release|Any CPU | {62BC3801-F0D3-44A9-A0AC-712F40C8F961}.Release|Any CPU.Build.0 = Release|Any CPU | ||||
{68861442-971A-4196-876E-C9330F0B3C54}.Debug|Any CPU.ActiveCfg = Debug|Any CPU | |||||
{68861442-971A-4196-876E-C9330F0B3C54}.Debug|Any CPU.Build.0 = Debug|Any CPU | |||||
{68861442-971A-4196-876E-C9330F0B3C54}.Release|Any CPU.ActiveCfg = Release|Any CPU | |||||
{68861442-971A-4196-876E-C9330F0B3C54}.Release|Any CPU.Build.0 = Release|Any CPU | |||||
EndGlobalSection | EndGlobalSection | ||||
GlobalSection(SolutionProperties) = preSolution | GlobalSection(SolutionProperties) = preSolution | ||||
HideSolutionNode = FALSE | HideSolutionNode = FALSE | ||||
@@ -0,0 +1,370 @@ | |||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?> | |||||
<!-- Created with Inkscape (http://www.inkscape.org/) --> | |||||
<svg | |||||
xmlns:dc="http://purl.org/dc/elements/1.1/" | |||||
xmlns:cc="http://creativecommons.org/ns#" | |||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" | |||||
xmlns:svg="http://www.w3.org/2000/svg" | |||||
xmlns="http://www.w3.org/2000/svg" | |||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" | |||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" | |||||
width="1026.6978" | |||||
height="328.57144" | |||||
viewBox="0 0 271.64711 86.934526" | |||||
version="1.1" | |||||
id="svg8" | |||||
sodipodi:docname="tf.net.architecture.svg" | |||||
inkscape:export-filename="tf.net.logo512.png" | |||||
inkscape:export-xdpi="138.45558" | |||||
inkscape:export-ydpi="138.45558" | |||||
inkscape:version="0.92.3 (2405546, 2018-03-11)"> | |||||
<defs | |||||
id="defs2" /> | |||||
<sodipodi:namedview | |||||
id="base" | |||||
pagecolor="#ffffff" | |||||
bordercolor="#666666" | |||||
borderopacity="1.0" | |||||
inkscape:pageopacity="0.0" | |||||
inkscape:pageshadow="2" | |||||
inkscape:zoom="0.98994949" | |||||
inkscape:cx="554.13667" | |||||
inkscape:cy="161.1291" | |||||
inkscape:document-units="mm" | |||||
inkscape:current-layer="layer1" | |||||
showgrid="false" | |||||
inkscape:snap-global="false" | |||||
showguides="false" | |||||
units="px" | |||||
inkscape:guide-bbox="true" | |||||
inkscape:window-width="1920" | |||||
inkscape:window-height="1017" | |||||
inkscape:window-x="1912" | |||||
inkscape:window-y="-8" | |||||
inkscape:window-maximized="1" | |||||
fit-margin-top="0" | |||||
fit-margin-left="0" | |||||
fit-margin-right="0" | |||||
fit-margin-bottom="0"> | |||||
<sodipodi:guide | |||||
position="-115.16765,123.92938" | |||||
orientation="1,0" | |||||
id="guide929" | |||||
inkscape:locked="false" /> | |||||
</sodipodi:namedview> | |||||
<metadata | |||||
id="metadata5"> | |||||
<rdf:RDF> | |||||
<cc:Work | |||||
rdf:about=""> | |||||
<dc:format>image/svg+xml</dc:format> | |||||
<dc:type | |||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" /> | |||||
<dc:title></dc:title> | |||||
</cc:Work> | |||||
</rdf:RDF> | |||||
</metadata> | |||||
<g | |||||
inkscape:label="Layer 1" | |||||
inkscape:groupmode="layer" | |||||
id="layer1" | |||||
transform="translate(8.3858147,-332.35208)"> | |||||
<g | |||||
id="g1279"> | |||||
<rect | |||||
y="332.35208" | |||||
x="-8.3858147" | |||||
height="86.934525" | |||||
width="271.64713" | |||||
id="rect1023" | |||||
style="opacity:1;vector-effect:none;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" /> | |||||
<text | |||||
id="text843" | |||||
y="347.40942" | |||||
x="18.269608" | |||||
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:9.87777805px;line-height:1.25;font-family:Calibri;-inkscape-font-specification:Calibri;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.26458332" | |||||
xml:space="preserve"><tspan | |||||
style="font-size:9.87777805px;stroke-width:0.26458332" | |||||
y="347.40942" | |||||
x="18.269608" | |||||
id="tspan841" | |||||
sodipodi:role="line">TensorFlow</tspan></text> | |||||
<g | |||||
transform="translate(0.53205782,8.3134011)" | |||||
id="g1009"> | |||||
<rect | |||||
rx="2.5349789" | |||||
style="opacity:1;vector-effect:none;fill:none;fill-opacity:1;fill-rule:nonzero;stroke:#865fc5;stroke-width:1.08041525;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" | |||||
id="rect845" | |||||
width="73.277794" | |||||
height="23.348486" | |||||
x="3.8228469" | |||||
y="379.87094" | |||||
ry="2.5349789" /> | |||||
<text | |||||
xml:space="preserve" | |||||
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:6.3499999px;line-height:1.25;font-family:Calibri;-inkscape-font-specification:Calibri;text-align:center;letter-spacing:0px;word-spacing:0px;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.18378384" | |||||
x="40.438488" | |||||
y="388.66986" | |||||
id="text849"><tspan | |||||
sodipodi:role="line" | |||||
x="41.157825" | |||||
y="388.66986" | |||||
style="font-size:6.3499999px;text-align:center;text-anchor:middle;stroke-width:0.18378384" | |||||
id="tspan851">Tensor Computation </tspan><tspan | |||||
sodipodi:role="line" | |||||
x="40.438488" | |||||
y="396.60736" | |||||
style="font-size:6.3499999px;text-align:center;text-anchor:middle;stroke-width:0.18378384" | |||||
id="tspan933">Layer (C++)</tspan></text> | |||||
</g> | |||||
<g | |||||
transform="translate(0.75958878,1.0971239)" | |||||
id="g1003"> | |||||
<text | |||||
xml:space="preserve" | |||||
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:6.3499999px;line-height:1.25;font-family:Calibri;-inkscape-font-specification:Calibri;text-align:center;letter-spacing:0px;word-spacing:0px;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.18378386" | |||||
x="40.093136" | |||||
y="363.23035" | |||||
id="text849-6"><tspan | |||||
sodipodi:role="line" | |||||
x="40.812473" | |||||
y="363.23035" | |||||
style="font-size:6.3499999px;text-align:center;text-anchor:middle;stroke-width:0.18378386" | |||||
id="tspan891">Graph Manipulation </tspan><tspan | |||||
sodipodi:role="line" | |||||
x="40.093136" | |||||
y="371.16785" | |||||
style="font-size:6.3499999px;text-align:center;text-anchor:middle;stroke-width:0.18378386" | |||||
id="tspan937">Layer (Python)</tspan></text> | |||||
<rect | |||||
rx="2.5349789" | |||||
style="opacity:1;vector-effect:none;fill:none;fill-opacity:1;fill-rule:nonzero;stroke:#865fc5;stroke-width:1.08041525;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" | |||||
id="rect845-1" | |||||
width="73.277794" | |||||
height="23.348486" | |||||
x="3.5953159" | |||||
y="353.88745" | |||||
ry="2.5349789" /> | |||||
</g> | |||||
<text | |||||
id="text843-5" | |||||
y="347.40942" | |||||
x="94.650604" | |||||
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:9.87777805px;line-height:1.25;font-family:Calibri;-inkscape-font-specification:Calibri;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.26458332" | |||||
xml:space="preserve"><tspan | |||||
style="font-size:9.87777805px;stroke-width:0.26458332" | |||||
y="347.40942" | |||||
x="94.650604" | |||||
id="tspan841-2" | |||||
sodipodi:role="line">TensorFlow.NET</tspan></text> | |||||
<g | |||||
transform="translate(-6.8241284,1.7065599)" | |||||
id="g1015"> | |||||
<rect | |||||
rx="2.5349789" | |||||
style="opacity:1;vector-effect:none;fill:none;fill-opacity:1;fill-rule:nonzero;stroke:#661f76;stroke-width:1.08041525;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" | |||||
id="rect845-1-8" | |||||
width="73.277794" | |||||
height="23.348486" | |||||
x="96.586525" | |||||
y="353.27802" | |||||
ry="2.5349789" /> | |||||
<text | |||||
xml:space="preserve" | |||||
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:6.3499999px;line-height:1.25;font-family:Calibri;-inkscape-font-specification:Calibri;text-align:center;letter-spacing:0px;word-spacing:0px;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.18378386" | |||||
x="133.686" | |||||
y="363.2756" | |||||
id="text849-6-2"><tspan | |||||
sodipodi:role="line" | |||||
x="134.40533" | |||||
y="363.2756" | |||||
style="font-size:6.3499999px;text-align:center;text-anchor:middle;stroke-width:0.18378386" | |||||
id="tspan891-9">Graph Manipulation </tspan><tspan | |||||
sodipodi:role="line" | |||||
x="133.686" | |||||
y="371.2131" | |||||
style="font-size:6.3499999px;text-align:center;text-anchor:middle;stroke-width:0.18378386" | |||||
id="tspan937-1">Layer (C#)</tspan></text> | |||||
</g> | |||||
<g | |||||
transform="translate(-9.932153,9.1901064)" | |||||
id="g1021"> | |||||
<rect | |||||
rx="2.5349789" | |||||
style="opacity:1;vector-effect:none;fill:none;fill-opacity:1;fill-rule:nonzero;stroke:#661f76;stroke-width:1.08041525;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" | |||||
id="rect845-2" | |||||
width="73.277794" | |||||
height="23.348486" | |||||
x="99.69455" | |||||
y="379.26151" | |||||
ry="2.5349789" /> | |||||
<text | |||||
xml:space="preserve" | |||||
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:6.3499999px;line-height:1.25;font-family:Calibri;-inkscape-font-specification:Calibri;text-align:center;letter-spacing:0px;word-spacing:0px;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.18378386" | |||||
x="136.3102" | |||||
y="388.29663" | |||||
id="text849-7"><tspan | |||||
sodipodi:role="line" | |||||
x="137.02953" | |||||
y="388.29663" | |||||
style="font-size:6.3499999px;text-align:center;text-anchor:middle;stroke-width:0.18378386" | |||||
id="tspan851-4">Tensor Computation </tspan><tspan | |||||
sodipodi:role="line" | |||||
x="136.3102" | |||||
y="396.23413" | |||||
style="font-size:6.3499999px;text-align:center;text-anchor:middle;stroke-width:0.18378386" | |||||
id="tspan933-3">Layer (C++)</tspan></text> | |||||
</g> | |||||
<g | |||||
transform="translate(20.221726,-55.562499)" | |||||
id="g1116"> | |||||
<rect | |||||
style="opacity:1;vector-effect:none;fill:none;fill-opacity:1;fill-rule:nonzero;stroke:#865fc5;stroke-width:1.08041525;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" | |||||
id="rect845-24" | |||||
width="73.277794" | |||||
height="9.9850101" | |||||
x="-15.866821" | |||||
y="433.88846" | |||||
ry="2.5349789" | |||||
rx="2.5349789" /> | |||||
<text | |||||
xml:space="preserve" | |||||
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:6.3499999px;line-height:1.25;font-family:Calibri;-inkscape-font-specification:Calibri;text-align:center;letter-spacing:0px;word-spacing:0px;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.18378384" | |||||
x="20.748819" | |||||
y="440.51651" | |||||
id="text849-5"><tspan | |||||
sodipodi:role="line" | |||||
x="20.748819" | |||||
y="440.51651" | |||||
style="font-size:6.3499999px;text-align:center;text-anchor:middle;stroke-width:0.18378384" | |||||
id="tspan851-42">C++ API (Python)</tspan><tspan | |||||
sodipodi:role="line" | |||||
x="20.748819" | |||||
y="448.45401" | |||||
style="font-size:6.3499999px;text-align:center;text-anchor:middle;stroke-width:0.18378384" | |||||
id="tspan933-9" /></text> | |||||
</g> | |||||
<g | |||||
transform="translate(105.62922,-55.3248)" | |||||
id="g1116-7"> | |||||
<rect | |||||
style="opacity:1;vector-effect:none;fill:none;fill-opacity:1;fill-rule:nonzero;stroke:#661f76;stroke-width:1.08041525;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" | |||||
id="rect845-24-6" | |||||
width="73.277794" | |||||
height="9.9850101" | |||||
x="-15.866821" | |||||
y="433.88846" | |||||
ry="2.5349789" | |||||
rx="2.5349789" /> | |||||
<text | |||||
xml:space="preserve" | |||||
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:6.3499999px;line-height:1.25;font-family:Calibri;-inkscape-font-specification:Calibri;text-align:center;letter-spacing:0px;word-spacing:0px;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.18378384" | |||||
x="20.748819" | |||||
y="440.51651" | |||||
id="text849-5-7"><tspan | |||||
sodipodi:role="line" | |||||
x="20.748819" | |||||
y="440.51651" | |||||
style="font-size:6.3499999px;text-align:center;text-anchor:middle;stroke-width:0.18378384" | |||||
id="tspan851-42-5">C++ API (C#)</tspan><tspan | |||||
sodipodi:role="line" | |||||
x="20.748819" | |||||
y="448.45401" | |||||
style="font-size:6.3499999px;text-align:center;text-anchor:middle;stroke-width:0.18378384" | |||||
id="tspan933-9-9" /></text> | |||||
</g> | |||||
<g | |||||
transform="translate(76.872688,8.5224453)" | |||||
id="g1021-2"> | |||||
<rect | |||||
rx="2.5349789" | |||||
style="opacity:1;vector-effect:none;fill:none;fill-opacity:1;fill-rule:nonzero;stroke:#661f76;stroke-width:1.08041525;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" | |||||
id="rect845-2-3" | |||||
width="73.277794" | |||||
height="23.348486" | |||||
x="99.69455" | |||||
y="379.26151" | |||||
ry="2.5349789" /> | |||||
<text | |||||
xml:space="preserve" | |||||
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:6.3499999px;line-height:1.25;font-family:Calibri;-inkscape-font-specification:Calibri;text-align:center;letter-spacing:0px;word-spacing:0px;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.18378386" | |||||
x="136.3102" | |||||
y="388.29663" | |||||
id="text849-7-1"><tspan | |||||
sodipodi:role="line" | |||||
x="137.02953" | |||||
y="388.29663" | |||||
style="font-size:6.3499999px;text-align:center;text-anchor:middle;stroke-width:0.18378386" | |||||
id="tspan851-4-6">Tensor Computation </tspan><tspan | |||||
sodipodi:role="line" | |||||
x="136.3102" | |||||
y="396.23413" | |||||
style="font-size:6.3499999px;text-align:center;text-anchor:middle;stroke-width:0.18378386" | |||||
id="tspan933-3-6">Layer (C++)</tspan></text> | |||||
</g> | |||||
<g | |||||
transform="translate(192.43406,-55.992467)" | |||||
id="g1116-7-2"> | |||||
<rect | |||||
style="opacity:1;vector-effect:none;fill:none;fill-opacity:1;fill-rule:nonzero;stroke:#661f76;stroke-width:1.08041525;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" | |||||
id="rect845-24-6-4" | |||||
width="73.277794" | |||||
height="9.9850101" | |||||
x="-15.866821" | |||||
y="433.88846" | |||||
ry="2.5349789" | |||||
rx="2.5349789" /> | |||||
<text | |||||
xml:space="preserve" | |||||
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:6.3499999px;line-height:1.25;font-family:Calibri;-inkscape-font-specification:Calibri;text-align:center;letter-spacing:0px;word-spacing:0px;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.18378384" | |||||
x="20.748819" | |||||
y="440.51651" | |||||
id="text849-5-7-7"><tspan | |||||
sodipodi:role="line" | |||||
x="20.748819" | |||||
y="440.51651" | |||||
style="font-size:6.3499999px;text-align:center;text-anchor:middle;stroke-width:0.18378384" | |||||
id="tspan851-42-5-9">C++ API (C#)</tspan><tspan | |||||
sodipodi:role="line" | |||||
x="20.748819" | |||||
y="448.45401" | |||||
style="font-size:6.3499999px;text-align:center;text-anchor:middle;stroke-width:0.18378384" | |||||
id="tspan933-9-9-0" /></text> | |||||
</g> | |||||
<text | |||||
id="text843-5-3" | |||||
y="346.74863" | |||||
x="179.03905" | |||||
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:9.87777805px;line-height:1.25;font-family:Calibri;-inkscape-font-specification:Calibri;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.26458332" | |||||
xml:space="preserve"><tspan | |||||
style="font-size:9.87777805px;stroke-width:0.26458332" | |||||
y="346.74863" | |||||
x="179.03905" | |||||
id="tspan841-2-9" | |||||
sodipodi:role="line">TensorFlowSharp</tspan><tspan | |||||
id="tspan1205" | |||||
style="font-size:9.87777805px;stroke-width:0.26458332" | |||||
y="359.09586" | |||||
x="179.03905" | |||||
sodipodi:role="line" /></text> | |||||
<text | |||||
id="text843-5-3-5" | |||||
y="355.52545" | |||||
x="192.88992" | |||||
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:7.11484385px;line-height:1.25;font-family:Calibri;-inkscape-font-specification:Calibri;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.26458332" | |||||
xml:space="preserve"><tspan | |||||
style="font-size:7.11484385px;stroke-width:0.26458332" | |||||
y="355.52545" | |||||
x="192.88992" | |||||
id="tspan841-2-9-8" | |||||
sodipodi:role="line">(by Microsoft)</tspan><tspan | |||||
id="tspan1205-0" | |||||
style="font-size:7.11484385px;stroke-width:0.26458332" | |||||
y="364.41901" | |||||
x="192.88992" | |||||
sodipodi:role="line" /></text> | |||||
</g> | |||||
</g> | |||||
</svg> |
@@ -0,0 +1,24 @@ | |||||
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> | |||||
<!-- | |||||
NuGet packages.config doesn't support native assemblies automatically, | |||||
so copy the native assemblies to the output directory. | |||||
--> | |||||
<ItemGroup Condition="Exists('packages.config') OR | |||||
Exists('$(MSBuildProjectName).packages.config') OR | |||||
Exists('packages.$(MSBuildProjectName).config')"> | |||||
<Content Include="$(MSBuildThisFileDirectory)\..\..\runtimes\win-x64\native\*.dll" | |||||
Condition="'$(PlatformTarget)' == 'x64'"> | |||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> | |||||
<Visible>false</Visible> | |||||
<Link>%(Filename)%(Extension)</Link> | |||||
</Content> | |||||
<Content Include="$(MSBuildThisFileDirectory)\..\..\runtimes\win-x86\native\*.dll" | |||||
Condition="'$(PlatformTarget)' == 'x86'"> | |||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> | |||||
<Visible>false</Visible> | |||||
<Link>%(Filename)%(Extension)</Link> | |||||
</Content> | |||||
</ItemGroup> | |||||
</Project> |
@@ -0,0 +1,188 @@ | |||||
<Project Sdk="Microsoft.NET.Sdk"> | |||||
<PropertyGroup> | |||||
<ProjDir>$(MSBuildThisFileDirectory)</ProjDir> | |||||
<BinDir>$(ProjDir)bin\</BinDir> | |||||
<ObjDir>$(ProjDir)obj\</ObjDir> | |||||
<TargetArchitecture Condition="'$(TargetArchitecture)' == ''">x64</TargetArchitecture> | |||||
<TargetFramework>netstandard2.0</TargetFramework> | |||||
<TensorFlowVersion>1.14.0</TensorFlowVersion> | |||||
<TensorFlowMajorVersion>1</TensorFlowMajorVersion> | |||||
<PackageAssetsPath>$(BinDir)packages\</PackageAssetsPath> | |||||
<PackageId>$(MSBuildProjectName)</PackageId> | |||||
<PackageVersion>$(TensorFlowVersion)</PackageVersion> | |||||
<NoBuild>true</NoBuild> | |||||
<IncludeBuildOutput>false</IncludeBuildOutput> | |||||
<NuspecFile>Redist.nuspec</NuspecFile> | |||||
<NuspecProperties>packageId=$(PackageId);version=$(PackageVersion)</NuspecProperties> | |||||
<NuspecBasePath>$(ProjDir)</NuspecBasePath> | |||||
<GenerateNuspecDependsOn>CopyFilesFromArchive</GenerateNuspecDependsOn> | |||||
<PackageRid Condition="'$(OS)' == 'Windows_NT'">win</PackageRid> | |||||
<PackageRid Condition="'$(OS)' != 'Windows_NT'">linux</PackageRid> | |||||
<PackageRid Condition="$([MSBuild]::IsOSPlatform('osx'))">osx</PackageRid> | |||||
<PackageRid>$(PackageRid)-$(TargetArchitecture)</PackageRid> | |||||
</PropertyGroup> | |||||
<PropertyGroup> | |||||
<IncludeMLNetNotices>false</IncludeMLNetNotices> | |||||
</PropertyGroup> | |||||
<ItemGroup> | |||||
<TensorFlowConfig Include="windows" | |||||
FileExtension=".zip" | |||||
FilesFromArchive="lib\tensorflow.dll; | |||||
include\tensorflow\c\LICENSE" | |||||
Runtime="win-x64"/> | |||||
<TensorFlowConfig Condition="'$(OS)' != 'Windows_NT'" | |||||
Include="linux" | |||||
FileExtension=".tar.gz" | |||||
FilesFromArchive="lib\libtensorflow.so; | |||||
lib\libtensorflow_framework.so.$(TensorFlowMajorVersion); | |||||
include\tensorflow\c\LICENSE" | |||||
Runtime="linux-x64" /> | |||||
<TensorFlowConfig Condition="'$(OS)' != 'Windows_NT'" | |||||
Include="darwin" FileExtension=".tar.gz" | |||||
FilesFromArchive="lib\libtensorflow.dylib; | |||||
lib\libtensorflow_framework.$(TensorFlowMajorVersion).dylib; | |||||
include\tensorflow\c\LICENSE" | |||||
Runtime="osx-x64" /> | |||||
<AdditionalDownloadFile Include="https://raw.githubusercontent.com/tensorflow/tensorflow/master/LICENSE" | |||||
DownloadFile="$(BinDir)LICENSE" /> | |||||
</ItemGroup> | |||||
<Target Name="PrepareArchives"> | |||||
<ItemGroup> | |||||
<!-- although we could extract all archives on all machines, mac requires a fixup which can only be run on mac | |||||
so we split these per-rid and join during the official build packaging. --> | |||||
<TensorFlowArchive | |||||
Include="@(TensorFlowConfig->'https://storage.googleapis.com/tensorflow/libtensorflow/libtensorflow-cpu-%(Identity)-x86_64-$(TensorFlowVersion)%(FileExtension)')" /> | |||||
<!-- set up metdata used by all targets --> | |||||
<TensorFlowArchive DownloadFile="$(BinDir)%(FileName)%(Extension)" | |||||
DownloadShaFile="$(BinDir)%(FileName)%(Extension).sha" | |||||
ExtractDirectory="$(BinDir)%(FileName)" | |||||
ExtractSemaphore="$(BinDir)%(FileName)\.extracted" | |||||
LocalShaFile="$(MSBuildProjectDirectory)\%(FileName)%(Extension).sha"/> | |||||
</ItemGroup> | |||||
<Message Importance="high" Text="%(TensorFlowConfig.Runtime)"/> | |||||
</Target> | |||||
<Target Name="DownloadArchives" | |||||
DependsOnTargets="PrepareArchives" | |||||
Inputs="$(MSBuildProjectFile)" | |||||
Outputs="@(TensorFlowArchive->'%(DownloadFile)');@(AdditionalDownloadFile->'%(DownloadFile)')"> | |||||
<MakeDir Directories="$(BinDir)" /> | |||||
<ItemGroup> | |||||
<_downloadFiles Include="@(TensorFlowArchive);@(AdditionalDownloadFile)" Url="%(Identity)" DestinationFile="%(DownloadFile)" /> | |||||
</ItemGroup> | |||||
<Message Importance="High" Text="Downloading '%(_downloadFiles.Identity)' to '$(BinDir)'." /> | |||||
<DownloadFile SourceUrl="%(_downloadFiles.Identity)" DestinationFolder="$(BinDir)"> | |||||
<Output TaskParameter="DownloadedFile" ItemName="Content" /> | |||||
</DownloadFile> | |||||
</Target> | |||||
<Target Name="ValidateAndExtractArchives" | |||||
DependsOnTargets="DownloadArchives" | |||||
Inputs="@(TensorFlowArchive->'%(DownloadFile)')" | |||||
Outputs="@(TensorFlowArchive->'%(ExtractSemaphore)')"> | |||||
<GetFileHash Files="@(TensorFlowArchive->'%(DownloadFile)')" Algorithm="SHA512"> | |||||
<Output | |||||
TaskParameter="Items" | |||||
ItemName="FilesWithHashes" /> | |||||
</GetFileHash> | |||||
<Message Importance="High" | |||||
Text="%(FilesWithHashes.Identity): %(FilesWithHashes.FileHash)" /> | |||||
<ItemGroup> | |||||
<TensorFlowArchive> | |||||
<DownloadSha>@(FilesWithHashes->'%(FileHash)')</DownloadSha> | |||||
<LocalSha>$([System.IO.File]::ReadAllText('%(LocalShaFile)'))</LocalSha> | |||||
</TensorFlowArchive> | |||||
</ItemGroup> | |||||
<!-- If specified we'll update the checked in SHAs with the downloaded ones. --> | |||||
<!--<WriteLinesToFile Condition="'$(UpdateSHA)' == 'true'" | |||||
File="@(TensorFlowArchive->'%(LocalShaFile)')" | |||||
Lines="@(TensorFlowArchive->'%(LocalShaFile)')" />--> | |||||
<Error Condition="!Exists('%(TensorFlowArchive.LocalShaFile)')" Text="SHA file '%(TensorFlowArchive.LocalShaFile)' does not exist. Build with /p:UpdateSHA=true to save it." /> | |||||
<Message Importance="High" Text="@TensorFlowArchive->'%(TensorFlowArchive.DownloadFile) - %(TensorFlowArchive.LocalSha) - %(TensorFlowArchive.DownloadSha)"/> | |||||
<!-- Validate that the downloaded SHAs match the expected checked in SHAs --> | |||||
<Error Condition="'%(TensorFlowArchive.LocalSha)' != '%(TensorFlowArchive.DownloadSha)'" Text="Downloaded file '%(TensorFlowArchive.DownloadFile)' has unexpected SHA.%0A expected: %(_downloadedTensorFlowArchive.LocalSha)%0A actual: %(_downloadedTensorFlowArchive.DownloadSha)%0ABuild with /p:UpdateSHA=true if you intentionally changed the URL and wish to update the SHAs, otherwise this could indicate an incomplete download or intercerpted URL and should be examined." /> | |||||
<!-- The archives are valid, lets extract them, ensuring an empty directory --> | |||||
<RemoveDir Directories="@(TensorFlowArchive->'%(ExtractDirectory)')" /> | |||||
<MakeDir Directories="@(TensorFlowArchive->'%(ExtractDirectory)')" /> | |||||
<Message Importance="High" Text="Decompressing '%(TensorFlowArchive.DownloadFile)' to '%(TensorFlowArchive.ExtractDirectory)'." /> | |||||
<Unzip Condition="'%(TensorFlowArchive.FileExtension)' == '.zip'" | |||||
SourceFiles="%(TensorFlowArchive.DownloadFile)" | |||||
DestinationFolder="%(TensorFlowArchive.ExtractDirectory)" /> | |||||
<Exec Condition="'$(OS)' != 'Windows_NT' AND '%(TensorFlowArchive.FileExtension)' == '.tar.gz'" | |||||
WorkingDirectory="$(MSBuildThisFileDirectory)" | |||||
Command="tar -xzm --hard-dereference -f %(TensorFlowArchive.DownloadFile) -C %(TensorFlowArchive.ExtractDirectory)" /> | |||||
<Exec Condition="'$(OS)' != 'Windows_NT'" | |||||
Command="chmod -R +w %(TensorFlowArchive.ExtractDirectory)" /> | |||||
<Touch Files="@(TensorFlowArchive->'%(ExtractSemaphore)')" AlwaysCreate="true" /> | |||||
</Target> | |||||
<!-- Select the files we want to copy out of each archive. --> | |||||
<Target Name="GetFilesFromArchive" | |||||
DependsOnTargets="ValidateAndExtractArchives" > | |||||
<ItemGroup> | |||||
<!-- batch rather than transform so that we can split FilesFromArchive metadata --> | |||||
<_fileFromArchive Include="%(TensorFlowArchive.FilesFromArchive)" ExtractDirectory="%(TensorFlowArchive.ExtractDirectory)" Runtime="%(TensorFlowArchive.Runtime)" /> | |||||
<_fileFromArchive DestinationFile="%(FileName)%(Extension)"/> | |||||
<_fileFromArchive PackagePath="runtimes\%(_fileFromArchive.Runtime)\native\%(_fileFromArchive.DestinationFile)" /> | |||||
<!-- LICENSE from the package is actually THIRD_PARTY_NOTICES--> | |||||
<_fileFromArchive Condition="'%(DestinationFile)' == 'LICENSE'" PackagePath="THIRD_PARTY_NOTICES.txt" Runtime="" /> | |||||
<!-- copy to packaging location --> | |||||
<FilesFromArchive Include="@(_fileFromArchive->'%(ExtractDirectory)\%(Identity)')" | |||||
TargetPath="$(PackageAssetsPath)$(MSBuildProjectName)\%(PackagePath)" /> | |||||
<!-- include LICENSE that was downloaded from GitHub --> | |||||
<FilesFromArchive Include="$(BinDir)\LICENSE" | |||||
TargetPath="$(PackageAssetsPath)$(MSBuildProjectName)\LICENSE.txt" /> | |||||
<!-- copy to NativeAssets location, only for current RID, so that they may be used by tests --> | |||||
<!--<FilesFromArchive Condition="'$(PackageRID)' == '%(_fileFromArchive.Runtime)'" | |||||
Include="@(_fileFromArchive->'%(ExtractDirectory)\%(Identity)')" | |||||
TargetPath="$(NativeAssetsBuiltPath)\%(_fileFromArchive.DestinationFile)" />--> | |||||
</ItemGroup> | |||||
</Target> | |||||
<Target Name="CopyFilesFromArchive" | |||||
DependsOnTargets="GetFilesFromArchive"> | |||||
<Message Importance="High" Text="@(FilesFromArchive) -> %(FilesFromArchive.TargetPath)" /> | |||||
<Copy SourceFiles="@(FilesFromArchive)" | |||||
DestinationFiles="@(FilesFromArchive->'%(TargetPath)')" /> | |||||
</Target> | |||||
<Target Name="Clean"> | |||||
<Message Importance="High" Text="Deleting $(BinDir);$(ObjDir)" /> | |||||
<RemoveDir Directories="$(BinDir);$(ObjDir)" /> | |||||
</Target> | |||||
</Project> |
@@ -0,0 +1 @@ | |||||
7002EF701BD23C5EF5FF94192E935F0DDF960A21BE2531CEE158586830C00E0BA889900F7F6E8AB568BEE0ACF1F5A6A246BB43D11C4109E9DC782B46377D8142 |
@@ -0,0 +1 @@ | |||||
E3F6D0309117E9E45780ECF8BC4D0268B3FC9F12E3E38FFE58496789330A4ACD2DC8FF721F3B8900357F6155F8A54000E45B99495F823486B558E8B42532392D |
@@ -0,0 +1 @@ | |||||
59A2B80B441439B851202358CE4A65BA0DDDB319A8A29E87B135DCD9954BC5B0628F2C0C8E72D6942EA3CDCE172805C2BD5421815B3D0210B62BC0936DC59A08 |
@@ -0,0 +1,26 @@ | |||||
<?xml version="1.0" encoding="utf-8"?> | |||||
<package xmlns="http://schemas.microsoft.com/packaging/2012/06/nuspec.xsd"> | |||||
<metadata> | |||||
<id>$packageId$</id> | |||||
<version>$version$</version> | |||||
<authors>The TensorFlow Authors</authors> | |||||
<owners>The TensorFlow Authors</owners> | |||||
<requireLicenseAcceptance>true</requireLicenseAcceptance> | |||||
<license type="file">LICENSE.txt</license> | |||||
<licenseUrl>https://aka.ms/deprecateLicenseUrl</licenseUrl> | |||||
<projectUrl>https://www.tensorflow.org/</projectUrl> | |||||
<description>$packageId$ contains the TensorFlow C library version $version$ redistributed as a NuGet package.</description> | |||||
<releaseNotes>https://github.com/tensorflow/tensorflow/releases/tag/v$version$</releaseNotes> | |||||
<copyright>Copyright 2019 The TensorFlow Authors. All rights reserved.</copyright> | |||||
<tags>TensorFlow</tags> | |||||
<dependencies> | |||||
<group targetFramework=".NETStandard2.0" /> | |||||
</dependencies> | |||||
</metadata> | |||||
<files> | |||||
<file src="CommonPackage.props" target="build\netstandard2.0\$packageId$.props" /> | |||||
<file src="bin\packages\$packageId$\LICENSE.txt" target="LICENSE.txt" /> | |||||
<file src="bin\packages\$packageId$\THIRD_PARTY_NOTICES.txt" target="THIRD_PARTY_NOTICES.txt" /> | |||||
<file src="bin\packages\$packageId$\runtimes\**\*" target="runtimes" /> | |||||
</files> | |||||
</package> |
@@ -1,6 +1,6 @@ | |||||
/***************************************************************************** | /***************************************************************************** | ||||
Copyright 2018 The TensorFlow.NET Authors. All Rights Reserved. | Copyright 2018 The TensorFlow.NET Authors. All Rights Reserved. | ||||
Licensed under the Apache License, Version 2.0 (the "License"); | Licensed under the Apache License, Version 2.0 (the "License"); | ||||
you may not use this file except in compliance with the License. | you may not use this file except in compliance with the License. | ||||
You may obtain a copy of the License at | You may obtain a copy of the License at | ||||
@@ -18,6 +18,8 @@ using NumSharp; | |||||
using System; | using System; | ||||
using System.Collections.Generic; | using System.Collections.Generic; | ||||
using System.Linq; | using System.Linq; | ||||
using System.Numerics; | |||||
using System.Runtime.CompilerServices; | |||||
using System.Runtime.InteropServices; | using System.Runtime.InteropServices; | ||||
using System.Text; | using System.Text; | ||||
using static Tensorflow.c_api; | using static Tensorflow.c_api; | ||||
@@ -36,39 +38,246 @@ namespace Tensorflow | |||||
_handle = handle; | _handle = handle; | ||||
} | } | ||||
public Tensor(NDArray nd, TF_DataType? tensorDType = null) | |||||
#if _REGEN | |||||
%types=["sbyte", "byte", "short", "ushort", "int", "uint", "long", "ulong", "float", "double", "Complex"] | |||||
%foreach types% | |||||
/// <summary> | |||||
/// Create a 1d Tensor from the given linear array and shape | |||||
/// </summary> | |||||
public Tensor(#1[] data) | |||||
{ | { | ||||
_handle = Allocate(nd, tensorDType: tensorDType); | |||||
_handle = CreateTensorWithoutCopying(dtypes.as_dtype(typeof(#1)), new long[]{data.Length}, data, Marshal.SizeOf<#1>()); | |||||
} | } | ||||
public unsafe Tensor(byte[] buffer) | |||||
/// <summary> | |||||
/// Create a N-dimensional Tensor from the given array | |||||
/// </summary> | |||||
public Tensor(#1[] data, long[] shape) | |||||
{ | { | ||||
var size = c_api.TF_StringEncodedSize((UIntPtr)buffer.Length); | |||||
_handle = TF_AllocateTensor(TF_DataType.TF_STRING, IntPtr.Zero, 0, (UIntPtr)((ulong)size + 8)); | |||||
_handle = CreateTensorWithoutCopying(dtypes.as_dtype(typeof(#1)), shape, data, Marshal.SizeOf<#1>()); | |||||
} | |||||
IntPtr tensor = c_api.TF_TensorData(_handle); | |||||
Marshal.WriteInt64(tensor, 0); | |||||
fixed (byte* src = &buffer[0]) | |||||
c_api.TF_StringEncode(src, (UIntPtr)buffer.Length, (sbyte*)(tensor + sizeof(Int64)), size, status); | |||||
% | |||||
#else | |||||
/// <summary> | |||||
/// Create a 1d Tensor from the given linear array and shape | |||||
/// </summary> | |||||
public Tensor(sbyte[] data) | |||||
{ | |||||
_handle = CreateTensorWithoutCopying(dtypes.as_dtype(typeof(sbyte)), new long[]{data.Length}, data, Marshal.SizeOf<sbyte>()); | |||||
} | |||||
status.Check(true); | |||||
/// <summary> | |||||
/// Create a N-dimensional Tensor from the given array | |||||
/// </summary> | |||||
public Tensor(sbyte[] data, long[] shape) | |||||
{ | |||||
_handle = CreateTensorWithoutCopying(dtypes.as_dtype(typeof(sbyte)), shape, data, Marshal.SizeOf<sbyte>()); | |||||
} | } | ||||
private IntPtr Allocate(NDArray nd, TF_DataType? tensorDType = null) | |||||
/// <summary> | |||||
/// Create a 1d Tensor from the given linear array and shape | |||||
/// </summary> | |||||
public Tensor(byte[] data) | |||||
{ | { | ||||
if (tensorDType == TF_DataType.TF_STRING && | |||||
nd.dtype.Name == "Byte") | |||||
_handle = CreateTensorWithoutCopying(dtypes.as_dtype(typeof(byte)), new long[]{data.Length}, data, Marshal.SizeOf<byte>()); | |||||
} | |||||
/// <summary> | |||||
/// Create a N-dimensional Tensor from the given array | |||||
/// </summary> | |||||
public Tensor(byte[] data, long[] shape) | |||||
{ | |||||
_handle = CreateTensorWithoutCopying(dtypes.as_dtype(typeof(byte)), shape, data, Marshal.SizeOf<byte>()); | |||||
} | |||||
/// <summary> | |||||
/// Create a 1d Tensor from the given linear array and shape | |||||
/// </summary> | |||||
public Tensor(short[] data) | |||||
{ | |||||
_handle = CreateTensorWithoutCopying(dtypes.as_dtype(typeof(short)), new long[]{data.Length}, data, Marshal.SizeOf<short>()); | |||||
} | |||||
/// <summary> | |||||
/// Create a N-dimensional Tensor from the given array | |||||
/// </summary> | |||||
public Tensor(short[] data, long[] shape) | |||||
{ | |||||
_handle = CreateTensorWithoutCopying(dtypes.as_dtype(typeof(short)), shape, data, Marshal.SizeOf<short>()); | |||||
} | |||||
/// <summary> | |||||
/// Create a 1d Tensor from the given linear array and shape | |||||
/// </summary> | |||||
public Tensor(ushort[] data) | |||||
{ | |||||
_handle = CreateTensorWithoutCopying(dtypes.as_dtype(typeof(ushort)), new long[]{data.Length}, data, Marshal.SizeOf<ushort>()); | |||||
} | |||||
/// <summary> | |||||
/// Create a N-dimensional Tensor from the given array | |||||
/// </summary> | |||||
public Tensor(ushort[] data, long[] shape) | |||||
{ | |||||
_handle = CreateTensorWithoutCopying(dtypes.as_dtype(typeof(ushort)), shape, data, Marshal.SizeOf<ushort>()); | |||||
} | |||||
/// <summary> | |||||
/// Create a 1d Tensor from the given linear array and shape | |||||
/// </summary> | |||||
public Tensor(int[] data) | |||||
{ | |||||
_handle = CreateTensorWithoutCopying(dtypes.as_dtype(typeof(int)), new long[]{data.Length}, data, Marshal.SizeOf<int>()); | |||||
} | |||||
/// <summary> | |||||
/// Create a N-dimensional Tensor from the given array | |||||
/// </summary> | |||||
public Tensor(int[] data, long[] shape) | |||||
{ | |||||
_handle = CreateTensorWithoutCopying(dtypes.as_dtype(typeof(int)), shape, data, Marshal.SizeOf<int>()); | |||||
} | |||||
/// <summary> | |||||
/// Create a 1d Tensor from the given linear array and shape | |||||
/// </summary> | |||||
public Tensor(uint[] data) | |||||
{ | |||||
_handle = CreateTensorWithoutCopying(dtypes.as_dtype(typeof(uint)), new long[]{data.Length}, data, Marshal.SizeOf<uint>()); | |||||
} | |||||
/// <summary> | |||||
/// Create a N-dimensional Tensor from the given array | |||||
/// </summary> | |||||
public Tensor(uint[] data, long[] shape) | |||||
{ | |||||
_handle = CreateTensorWithoutCopying(dtypes.as_dtype(typeof(uint)), shape, data, Marshal.SizeOf<uint>()); | |||||
} | |||||
/// <summary> | |||||
/// Create a 1d Tensor from the given linear array and shape | |||||
/// </summary> | |||||
public Tensor(long[] data) | |||||
{ | |||||
_handle = CreateTensorWithoutCopying(dtypes.as_dtype(typeof(long)), new long[]{data.Length}, data, Marshal.SizeOf<long>()); | |||||
} | |||||
/// <summary> | |||||
/// Create a N-dimensional Tensor from the given array | |||||
/// </summary> | |||||
public Tensor(long[] data, long[] shape) | |||||
{ | |||||
_handle = CreateTensorWithoutCopying(dtypes.as_dtype(typeof(long)), shape, data, Marshal.SizeOf<long>()); | |||||
} | |||||
/// <summary> | |||||
/// Create a 1d Tensor from the given linear array and shape | |||||
/// </summary> | |||||
public Tensor(ulong[] data) | |||||
{ | |||||
_handle = CreateTensorWithoutCopying(dtypes.as_dtype(typeof(ulong)), new long[]{data.Length}, data, Marshal.SizeOf<ulong>()); | |||||
} | |||||
/// <summary> | |||||
/// Create a N-dimensional Tensor from the given array | |||||
/// </summary> | |||||
public Tensor(ulong[] data, long[] shape) | |||||
{ | |||||
_handle = CreateTensorWithoutCopying(dtypes.as_dtype(typeof(ulong)), shape, data, Marshal.SizeOf<ulong>()); | |||||
} | |||||
/// <summary> | |||||
/// Create a 1d Tensor from the given linear array and shape | |||||
/// </summary> | |||||
public Tensor(float[] data) | |||||
{ | |||||
_handle = CreateTensorWithoutCopying(dtypes.as_dtype(typeof(float)), new long[]{data.Length}, data, Marshal.SizeOf<float>()); | |||||
} | |||||
/// <summary> | |||||
/// Create a N-dimensional Tensor from the given array | |||||
/// </summary> | |||||
public Tensor(float[] data, long[] shape) | |||||
{ | |||||
_handle = CreateTensorWithoutCopying(dtypes.as_dtype(typeof(float)), shape, data, Marshal.SizeOf<float>()); | |||||
} | |||||
/// <summary> | |||||
/// Create a 1d Tensor from the given linear array and shape | |||||
/// </summary> | |||||
public Tensor(double[] data) | |||||
{ | |||||
_handle = CreateTensorWithoutCopying(dtypes.as_dtype(typeof(double)), new long[]{data.Length}, data, Marshal.SizeOf<double>()); | |||||
} | |||||
/// <summary> | |||||
/// Create a N-dimensional Tensor from the given array | |||||
/// </summary> | |||||
public Tensor(double[] data, long[] shape) | |||||
{ | |||||
_handle = CreateTensorWithoutCopying(dtypes.as_dtype(typeof(double)), shape, data, Marshal.SizeOf<double>()); | |||||
} | |||||
/// <summary> | |||||
/// Create a 1d Tensor from the given linear array and shape | |||||
/// </summary> | |||||
public Tensor(Complex[] data) | |||||
{ | |||||
_handle = CreateTensorWithoutCopying(dtypes.as_dtype(typeof(Complex)), new long[]{data.Length}, data, Marshal.SizeOf<Complex>()); | |||||
} | |||||
/// <summary> | |||||
/// Create a N-dimensional Tensor from the given array | |||||
/// </summary> | |||||
public Tensor(Complex[] data, long[] shape) | |||||
{ | |||||
_handle = CreateTensorWithoutCopying(dtypes.as_dtype(typeof(Complex)), shape, data, Marshal.SizeOf<Complex>()); | |||||
} | |||||
#endif | |||||
public Tensor(NDArray nd, TF_DataType? tensorDType = null) | |||||
{ | |||||
_handle = Allocate(nd, tensorDType: tensorDType); | |||||
} | |||||
private unsafe IntPtr Allocate(NDArray nd, TF_DataType? tensorDType = null) | |||||
{ | |||||
if (tensorDType == TF_DataType.TF_STRING && nd.dtype.Name == "Byte") | |||||
{ | { | ||||
return new Tensor(nd.Data<byte>()); | |||||
var buffer=nd.Data<byte>(); | |||||
var size = c_api.TF_StringEncodedSize((UIntPtr)buffer.Length); | |||||
var handle = TF_AllocateTensor(TF_DataType.TF_STRING, IntPtr.Zero, 0, (UIntPtr)((ulong)size + 8)); | |||||
IntPtr tensor = c_api.TF_TensorData(handle); | |||||
Marshal.WriteInt64(tensor, 0); | |||||
fixed (byte* src = &buffer[0]) | |||||
c_api.TF_StringEncode(src, (UIntPtr)buffer.Length, (sbyte*)(tensor + sizeof(Int64)), size, status); | |||||
status.Check(true); | |||||
return handle; | |||||
} | } | ||||
IntPtr dotHandle = IntPtr.Zero; | IntPtr dotHandle = IntPtr.Zero; | ||||
ulong size = 0; | |||||
int buffersize = 0; | |||||
if (nd.dtype.Name != "String") | if (nd.dtype.Name != "String") | ||||
{ | { | ||||
dotHandle = Marshal.AllocHGlobal(nd.dtypesize * nd.size); | |||||
size = (ulong)(nd.size * nd.dtypesize); | |||||
buffersize = (nd.size * nd.dtypesize); | |||||
dotHandle = Marshal.AllocHGlobal(buffersize); | |||||
} | } | ||||
var dataType = ToTFDataType(nd.dtype); | var dataType = ToTFDataType(nd.dtype); | ||||
@@ -116,7 +325,7 @@ namespace Tensorflow | |||||
dims, | dims, | ||||
dims.Length, | dims.Length, | ||||
dotHandle, | dotHandle, | ||||
(UIntPtr)size, | |||||
(UIntPtr)buffersize, | |||||
deallocator, | deallocator, | ||||
ref deallocator_called); | ref deallocator_called); | ||||
@@ -130,5 +339,59 @@ namespace Tensorflow | |||||
_dtype = dtype; | _dtype = dtype; | ||||
_id = ops.uid(); | _id = ops.uid(); | ||||
} | } | ||||
/// <summary> | |||||
/// Creates a new tensor from the given array without copying memory. The array is pinned down and the pointer passed on. | |||||
/// </summary> | |||||
/// <param name="shape">Represents the tensor shape.</param> | |||||
/// <param name="data">The linear array of data, the data must fit in the tensor with the specified dimensions.</param> | |||||
/// <param name="element_size">The number of bytes in memory of a single array element</param> | |||||
/// <remarks> | |||||
/// Use the FromBuffer method to create a tensor that has the specified dimensions | |||||
/// and is initialized with data from the data array. The data is copied starting | |||||
/// at the start offset, for count bytes and is laid out into the tensor following the | |||||
/// specified dimensions. | |||||
/// </remarks> | |||||
[MethodImpl(MethodImplOptions.AggressiveInlining)] | |||||
protected IntPtr CreateTensorWithoutCopying(TF_DataType dt, long[] shape, Array data, int element_size) | |||||
{ | |||||
return CreateTensorWithoutCopying(dt, shape, data, 0, data.Length, element_size); | |||||
} | |||||
/// <summary> | |||||
/// Creates a new tensor from a subsection of the given array without copying memory. The array is pinned down and the pointer passed on. | |||||
/// </summary> | |||||
/// <param name="shape">Represents the tensor shape.</param> | |||||
/// <param name="data">The linear array of data, the data must fit in the tensor with the specified dimensions.</param> | |||||
/// <param name="start">The offset into the provided data array where the data resides.</param> | |||||
/// <param name="count">The number of elements to copy from data.</param> | |||||
/// <param name="element_size">The number of bytes in memory of a single array element</param> | |||||
/// <remarks> | |||||
/// Use the FromBuffer method to create a tensor that has the specified dimensions | |||||
/// and is initialized with data from the data array. The data is copied starting | |||||
/// at the start offset, for count bytes and is laid out into the tensor following the | |||||
/// specified dimensions. | |||||
/// </remarks> | |||||
[MethodImpl(MethodImplOptions.AggressiveInlining)] | |||||
protected IntPtr CreateTensorWithoutCopying(TF_DataType dt, long[] shape, Array data, int start, int count, int element_size) | |||||
{ | |||||
if (start < 0 || start > data.Length - count) | |||||
throw new ArgumentException($"Array length {data.Length} does not match the given shape {new Shape(shape.Cast<int>().ToArray())}"); | |||||
// get a handle to the pinned array which we will pass on to the tensor computation engine to use | |||||
var dataHandle = GCHandle.Alloc(data, GCHandleType.Pinned); | |||||
// Free the original buffer and set flag | |||||
Deallocator deallocator = (IntPtr values, IntPtr len, ref bool closure) => | |||||
{ | |||||
dataHandle.Free(); | |||||
closure = true; | |||||
}; | |||||
if (shape == null) | |||||
return TF_NewTensor(dt, null, 0, dataHandle.AddrOfPinnedObject() + start * element_size, (UIntPtr)(count * element_size), deallocator, ref deallocator_called); | |||||
else | |||||
return TF_NewTensor(dt, shape, shape.Length, dataHandle.AddrOfPinnedObject() + start * element_size, (UIntPtr)(count * element_size), deallocator, ref deallocator_called); | |||||
} | |||||
} | } | ||||
} | } |
@@ -31,7 +31,7 @@ namespace Tensorflow | |||||
/// </summary> | /// </summary> | ||||
public partial class Tensor : IDisposable, ITensorOrOperation | public partial class Tensor : IDisposable, ITensorOrOperation | ||||
{ | { | ||||
private readonly IntPtr _handle; | |||||
private IntPtr _handle; | |||||
private int _id; | private int _id; | ||||
private Operation _op; | private Operation _op; | ||||
@@ -351,6 +351,7 @@ namespace Tensorflow | |||||
public void Dispose() | public void Dispose() | ||||
{ | { | ||||
c_api.TF_DeleteTensor(_handle); | c_api.TF_DeleteTensor(_handle); | ||||
_handle = IntPtr.Zero; | |||||
status.Dispose(); | status.Dispose(); | ||||
} | } | ||||
@@ -52,32 +52,51 @@ namespace Tensorflow | |||||
} | } | ||||
} | } | ||||
// "sbyte", "byte", "short", "ushort", "int", "uint", "long", "ulong", "float", "double", "Complex" | |||||
public static TF_DataType as_dtype(Type type) | public static TF_DataType as_dtype(Type type) | ||||
{ | { | ||||
TF_DataType dtype = TF_DataType.DtInvalid; | TF_DataType dtype = TF_DataType.DtInvalid; | ||||
switch (type.Name) | switch (type.Name) | ||||
{ | { | ||||
case "Boolean": | |||||
dtype = TF_DataType.TF_BOOL; | |||||
case "SByte": | |||||
dtype = TF_DataType.TF_INT8; | |||||
break; | |||||
case "Byte": | |||||
dtype = TF_DataType.TF_UINT8; | |||||
break; | |||||
case "Int16": | |||||
dtype = TF_DataType.TF_INT16; | |||||
break; | |||||
case "UInt16": | |||||
dtype = TF_DataType.TF_UINT16; | |||||
break; | break; | ||||
case "Int32": | case "Int32": | ||||
dtype = TF_DataType.TF_INT32; | dtype = TF_DataType.TF_INT32; | ||||
break; | break; | ||||
case "UInt32": | |||||
dtype = TF_DataType.TF_UINT32; | |||||
break; | |||||
case "Int64": | case "Int64": | ||||
dtype = TF_DataType.TF_INT64; | dtype = TF_DataType.TF_INT64; | ||||
break; | break; | ||||
case "UInt64": | |||||
dtype = TF_DataType.TF_UINT64; | |||||
break; | |||||
case "Single": | case "Single": | ||||
dtype = TF_DataType.TF_FLOAT; | dtype = TF_DataType.TF_FLOAT; | ||||
break; | break; | ||||
case "Double": | case "Double": | ||||
dtype = TF_DataType.TF_DOUBLE; | dtype = TF_DataType.TF_DOUBLE; | ||||
break; | break; | ||||
case "Complex": | |||||
dtype = TF_DataType.TF_COMPLEX128; | |||||
break; | |||||
case "String": | case "String": | ||||
dtype = TF_DataType.TF_STRING; | dtype = TF_DataType.TF_STRING; | ||||
break; | break; | ||||
case "Byte": | |||||
dtype = TF_DataType.TF_STRING; | |||||
case "Boolean": | |||||
dtype = TF_DataType.TF_BOOL; | |||||
break; | break; | ||||
default: | default: | ||||
throw new Exception("as_dtype Not Implemented"); | throw new Exception("as_dtype Not Implemented"); | ||||
@@ -41,7 +41,11 @@ namespace Tensorflow | |||||
public void close_variable_subscopes(string scope_name) | public void close_variable_subscopes(string scope_name) | ||||
{ | { | ||||
var variable_scopes_count_tmp = new Dictionary<string, int>(); | |||||
foreach (var k in variable_scopes_count.Keys) | foreach (var k in variable_scopes_count.Keys) | ||||
variable_scopes_count_tmp.Add(k, variable_scopes_count[k]); | |||||
foreach (var k in variable_scopes_count_tmp.Keys) | |||||
if (scope_name == null || k.StartsWith(scope_name + "/")) | if (scope_name == null || k.StartsWith(scope_name + "/")) | ||||
variable_scopes_count[k] = 0; | variable_scopes_count[k] = 0; | ||||
} | } | ||||
@@ -0,0 +1,40 @@ | |||||
using System; | |||||
using System.Reflection; | |||||
using BenchmarkDotNet.Configs; | |||||
using BenchmarkDotNet.Running; | |||||
namespace TensorFlowNet.Benchmark | |||||
{ | |||||
class Program | |||||
{ | |||||
/// <summary> | |||||
/// dotnet NumSharp.Benchmark.dll (Benchmark Class Name) | |||||
/// dotnet NumSharp.Benchmark.dll nparange | |||||
/// </summary> | |||||
/// <param name="args"></param> | |||||
static void Main(string[] args) | |||||
{ | |||||
#if DEBUG | |||||
IConfig config = new DebugInProcessConfig(); | |||||
#else | |||||
IConfig config = null; | |||||
#endif | |||||
if (args?.Length > 0) | |||||
{ | |||||
for (int i = 0; i < args.Length; i++) | |||||
{ | |||||
string name = $"TensorFlowNet.Benchmark.{args[i]}"; | |||||
var type = Type.GetType(name); | |||||
BenchmarkRunner.Run(type, config); | |||||
} | |||||
} | |||||
else | |||||
{ | |||||
BenchmarkSwitcher.FromAssembly(Assembly.GetExecutingAssembly()).Run(args, config); | |||||
} | |||||
Console.ReadLine(); | |||||
} | |||||
} | |||||
} |
@@ -0,0 +1,55 @@ | |||||
using System; | |||||
using System.Linq; | |||||
using BenchmarkDotNet.Attributes; | |||||
using BenchmarkDotNet.Engines; | |||||
using NumSharp; | |||||
using Tensorflow; | |||||
namespace TensorFlowNet.Benchmark | |||||
{ | |||||
[SimpleJob(launchCount: 1, warmupCount: 10, targetCount: 30)] | |||||
[MinColumn, MaxColumn, MeanColumn, MedianColumn] | |||||
public class TensorCreation | |||||
{ | |||||
private double[] data; | |||||
[GlobalSetup] | |||||
public void Setup() | |||||
{ | |||||
data = new double[1000]; | |||||
} | |||||
[Benchmark] | |||||
public void TensorFromArray() | |||||
{ | |||||
var g=new Graph(); | |||||
for (int i = 0; i < 100; i++) | |||||
{ | |||||
var tensor = new Tensor(data); | |||||
} | |||||
} | |||||
[Benchmark] | |||||
public void TensorFromNDArray() | |||||
{ | |||||
var g = new Graph(); | |||||
for (int i = 0; i < 100; i++) | |||||
{ | |||||
var tensor = new Tensor(new NDArray(data)); | |||||
} | |||||
} | |||||
//[Benchmark] | |||||
//public void Constant() | |||||
//{ | |||||
// for (int i = 0; i < 100; i++) | |||||
// { | |||||
// //var tensor = new Tensor(new NDArray(data)); | |||||
// var c = tf.constant(42.0); | |||||
// } | |||||
//} | |||||
} | |||||
} | |||||
@@ -0,0 +1,22 @@ | |||||
<Project Sdk="Microsoft.NET.Sdk"> | |||||
<PropertyGroup> | |||||
<OutputType>Exe</OutputType> | |||||
<TargetFramework>netcoreapp2.2</TargetFramework> | |||||
</PropertyGroup> | |||||
<ItemGroup> | |||||
<PackageReference Include="BenchmarkDotNet" Version="0.11.5" /> | |||||
</ItemGroup> | |||||
<ItemGroup> | |||||
<ProjectReference Include="..\TensorFlowNET.Core\TensorFlowNET.Core.csproj" /> | |||||
</ItemGroup> | |||||
<ItemGroup> | |||||
<None Update="tensorflow.dll"> | |||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> | |||||
</None> | |||||
</ItemGroup> | |||||
</Project> |
@@ -73,6 +73,10 @@ namespace TensorFlowNET.Examples.ImageProcess | |||||
float accuracy_test = 0f; | float accuracy_test = 0f; | ||||
float loss_test = 1f; | float loss_test = 1f; | ||||
NDArray x_train, y_train; | |||||
NDArray x_valid, y_valid; | |||||
NDArray x_test, y_test; | |||||
public bool Run() | public bool Run() | ||||
{ | { | ||||
PrepareData(); | PrepareData(); | ||||
@@ -133,6 +137,62 @@ namespace TensorFlowNET.Examples.ImageProcess | |||||
return graph; | return graph; | ||||
} | } | ||||
public void Train(Session sess) | |||||
{ | |||||
// Number of training iterations in each epoch | |||||
var num_tr_iter = y_train.len / batch_size; | |||||
var init = tf.global_variables_initializer(); | |||||
sess.run(init); | |||||
float loss_val = 100.0f; | |||||
float accuracy_val = 0f; | |||||
foreach (var epoch in range(epochs)) | |||||
{ | |||||
print($"Training epoch: {epoch + 1}"); | |||||
// Randomly shuffle the training data at the beginning of each epoch | |||||
(x_train, y_train) = mnist.Randomize(x_train, y_train); | |||||
foreach (var iteration in range(num_tr_iter)) | |||||
{ | |||||
var start = iteration * batch_size; | |||||
var end = (iteration + 1) * batch_size; | |||||
var (x_batch, y_batch) = mnist.GetNextBatch(x_train, y_train, start, end); | |||||
// Run optimization op (backprop) | |||||
sess.run(optimizer, new FeedItem(x, x_batch), new FeedItem(y, y_batch)); | |||||
if (iteration % display_freq == 0) | |||||
{ | |||||
// Calculate and display the batch loss and accuracy | |||||
var result = sess.run(new[] { loss, accuracy }, new FeedItem(x, x_batch), new FeedItem(y, y_batch)); | |||||
loss_val = result[0]; | |||||
accuracy_val = result[1]; | |||||
print($"iter {iteration.ToString("000")}: Loss={loss_val.ToString("0.0000")}, Training Accuracy={accuracy_val.ToString("P")}"); | |||||
} | |||||
} | |||||
// Run validation after every epoch | |||||
var results1 = sess.run(new[] { loss, accuracy }, new FeedItem(x, x_valid), new FeedItem(y, y_valid)); | |||||
loss_val = results1[0]; | |||||
accuracy_val = results1[1]; | |||||
print("---------------------------------------------------------"); | |||||
print($"Epoch: {epoch + 1}, validation loss: {loss_val.ToString("0.0000")}, validation accuracy: {accuracy_val.ToString("P")}"); | |||||
print("---------------------------------------------------------"); | |||||
} | |||||
} | |||||
public void Test(Session sess) | |||||
{ | |||||
var result = sess.run(new[] { loss, accuracy }, new FeedItem(x, x_test), new FeedItem(y, y_test)); | |||||
loss_test = result[0]; | |||||
accuracy_test = result[1]; | |||||
print("---------------------------------------------------------"); | |||||
print($"Test loss: {loss_test.ToString("0.0000")}, test accuracy: {accuracy_test.ToString("P")}"); | |||||
print("---------------------------------------------------------"); | |||||
} | |||||
/// <summary> | /// <summary> | ||||
/// Create a 2D convolution layer | /// Create a 2D convolution layer | ||||
/// </summary> | /// </summary> | ||||
@@ -217,6 +277,14 @@ namespace TensorFlowNET.Examples.ImageProcess | |||||
initializer: initial); | initializer: initial); | ||||
} | } | ||||
/// <summary> | |||||
/// Create a fully-connected layer | |||||
/// </summary> | |||||
/// <param name="x">input from previous layer</param> | |||||
/// <param name="num_units">number of hidden units in the fully-connected layer</param> | |||||
/// <param name="name">layer name</param> | |||||
/// <param name="use_relu">boolean to add ReLU non-linearity (or not)</param> | |||||
/// <returns>The output array</returns> | |||||
private Tensor fc_layer(Tensor x, int num_units, string name, bool use_relu = true) | private Tensor fc_layer(Tensor x, int num_units, string name, bool use_relu = true) | ||||
{ | { | ||||
return with(tf.variable_scope(name), delegate | return with(tf.variable_scope(name), delegate | ||||
@@ -233,73 +301,36 @@ namespace TensorFlowNET.Examples.ImageProcess | |||||
return layer; | return layer; | ||||
}); | }); | ||||
} | } | ||||
public Graph ImportGraph() => throw new NotImplementedException(); | |||||
public void Predict(Session sess) => throw new NotImplementedException(); | |||||
public void PrepareData() | public void PrepareData() | ||||
{ | { | ||||
mnist = MNIST.read_data_sets("mnist", one_hot: true); | mnist = MNIST.read_data_sets("mnist", one_hot: true); | ||||
(x_train, y_train) = Reformat(mnist.train.data, mnist.train.labels); | |||||
(x_valid, y_valid) = Reformat(mnist.validation.data, mnist.validation.labels); | |||||
(x_test, y_test) = Reformat(mnist.test.data, mnist.test.labels); | |||||
print("Size of:"); | print("Size of:"); | ||||
print($"- Training-set:\t\t{len(mnist.train.data)}"); | print($"- Training-set:\t\t{len(mnist.train.data)}"); | ||||
print($"- Validation-set:\t{len(mnist.validation.data)}"); | print($"- Validation-set:\t{len(mnist.validation.data)}"); | ||||
} | } | ||||
public void Train(Session sess) | |||||
/// <summary> | |||||
/// Reformats the data to the format acceptable for convolutional layers | |||||
/// </summary> | |||||
/// <param name="x"></param> | |||||
/// <param name="y"></param> | |||||
/// <returns></returns> | |||||
private (NDArray, NDArray) Reformat(NDArray x, NDArray y) | |||||
{ | { | ||||
// Number of training iterations in each epoch | |||||
var num_tr_iter = mnist.train.labels.len / batch_size; | |||||
var init = tf.global_variables_initializer(); | |||||
sess.run(init); | |||||
float loss_val = 100.0f; | |||||
float accuracy_val = 0f; | |||||
foreach (var epoch in range(epochs)) | |||||
{ | |||||
print($"Training epoch: {epoch + 1}"); | |||||
// Randomly shuffle the training data at the beginning of each epoch | |||||
var (x_train, y_train) = mnist.Randomize(mnist.train.data, mnist.train.labels); | |||||
foreach (var iteration in range(num_tr_iter)) | |||||
{ | |||||
var start = iteration * batch_size; | |||||
var end = (iteration + 1) * batch_size; | |||||
var (x_batch, y_batch) = mnist.GetNextBatch(x_train, y_train, start, end); | |||||
// Run optimization op (backprop) | |||||
sess.run(optimizer, new FeedItem(x, x_batch), new FeedItem(y, y_batch)); | |||||
if (iteration % display_freq == 0) | |||||
{ | |||||
// Calculate and display the batch loss and accuracy | |||||
var result = sess.run(new[] { loss, accuracy }, new FeedItem(x, x_batch), new FeedItem(y, y_batch)); | |||||
loss_val = result[0]; | |||||
accuracy_val = result[1]; | |||||
print($"iter {iteration.ToString("000")}: Loss={loss_val.ToString("0.0000")}, Training Accuracy={accuracy_val.ToString("P")}"); | |||||
} | |||||
} | |||||
// Run validation after every epoch | |||||
var results1 = sess.run(new[] { loss, accuracy }, new FeedItem(x, mnist.validation.data), new FeedItem(y, mnist.validation.labels)); | |||||
loss_val = results1[0]; | |||||
accuracy_val = results1[1]; | |||||
print("---------------------------------------------------------"); | |||||
print($"Epoch: {epoch + 1}, validation loss: {loss_val.ToString("0.0000")}, validation accuracy: {accuracy_val.ToString("P")}"); | |||||
print("---------------------------------------------------------"); | |||||
} | |||||
var (img_size, num_ch, num_class) = (np.sqrt(x.shape[1]), 1, len(np.unique<int>(np.argmax(y, 1)))); | |||||
var dataset = x.reshape(x.shape[0], img_size, img_size, num_ch).astype(np.float32); | |||||
//y[0] = np.arange(num_class) == y[0]; | |||||
//var labels = (np.arange(num_class) == y.reshape(y.shape[0], 1, y.shape[1])).astype(np.float32); | |||||
return (dataset, y); | |||||
} | } | ||||
public void Test(Session sess) | |||||
{ | |||||
var result = sess.run(new[] { loss, accuracy }, new FeedItem(x, mnist.test.data), new FeedItem(y, mnist.test.labels)); | |||||
loss_test = result[0]; | |||||
accuracy_test = result[1]; | |||||
print("---------------------------------------------------------"); | |||||
print($"Test loss: {loss_test.ToString("0.0000")}, test accuracy: {accuracy_test.ToString("P")}"); | |||||
print("---------------------------------------------------------"); | |||||
} | |||||
public Graph ImportGraph() => throw new NotImplementedException(); | |||||
public void Predict(Session sess) => throw new NotImplementedException(); | |||||
} | } | ||||
} | } |
@@ -32,7 +32,7 @@ namespace TensorFlowNET.Examples | |||||
{ | { | ||||
public bool Enabled { get; set; } = true; | public bool Enabled { get; set; } = true; | ||||
public string Name => "Object Detection"; | public string Name => "Object Detection"; | ||||
public bool IsImportingGraph { get; set; } = false; | |||||
public bool IsImportingGraph { get; set; } = true; | |||||
public float MIN_SCORE = 0.5f; | public float MIN_SCORE = 0.5f; | ||||
@@ -42,16 +42,34 @@ namespace TensorFlowNET.Examples | |||||
string labelFile = "mscoco_label_map.pbtxt"; | string labelFile = "mscoco_label_map.pbtxt"; | ||||
string picFile = "input.jpg"; | string picFile = "input.jpg"; | ||||
NDArray imgArr; | |||||
public bool Run() | public bool Run() | ||||
{ | { | ||||
PrepareData(); | PrepareData(); | ||||
// read in the input image | // read in the input image | ||||
var imgArr = ReadTensorFromImageFile(Path.Join(imageDir, "input.jpg")); | |||||
imgArr = ReadTensorFromImageFile(Path.Join(imageDir, "input.jpg")); | |||||
var graph = IsImportingGraph ? ImportGraph() : BuildGraph(); | |||||
with(tf.Session(graph), sess => Predict(sess)); | |||||
var graph = new Graph().as_default(); | |||||
return true; | |||||
} | |||||
public Graph ImportGraph() | |||||
{ | |||||
var graph = new Graph().as_default(); | |||||
graph.Import(Path.Join(modelDir, pbFile)); | graph.Import(Path.Join(modelDir, pbFile)); | ||||
return graph; | |||||
} | |||||
public void Predict(Session sess) | |||||
{ | |||||
var graph = tf.get_default_graph(); | |||||
Tensor tensorNum = graph.OperationByName("num_detections"); | Tensor tensorNum = graph.OperationByName("num_detections"); | ||||
Tensor tensorBoxes = graph.OperationByName("detection_boxes"); | Tensor tensorBoxes = graph.OperationByName("detection_boxes"); | ||||
Tensor tensorScores = graph.OperationByName("detection_scores"); | Tensor tensorScores = graph.OperationByName("detection_scores"); | ||||
@@ -59,16 +77,11 @@ namespace TensorFlowNET.Examples | |||||
Tensor imgTensor = graph.OperationByName("image_tensor"); | Tensor imgTensor = graph.OperationByName("image_tensor"); | ||||
Tensor[] outTensorArr = new Tensor[] { tensorNum, tensorBoxes, tensorScores, tensorClasses }; | Tensor[] outTensorArr = new Tensor[] { tensorNum, tensorBoxes, tensorScores, tensorClasses }; | ||||
with(tf.Session(graph), sess => | |||||
{ | |||||
var results = sess.run(outTensorArr, new FeedItem(imgTensor, imgArr)); | |||||
NDArray[] resultArr = results.Data<NDArray>(); | |||||
buildOutputImage(resultArr); | |||||
}); | |||||
var results = sess.run(outTensorArr, new FeedItem(imgTensor, imgArr)); | |||||
return true; | |||||
NDArray[] resultArr = results.Data<NDArray>(); | |||||
buildOutputImage(resultArr); | |||||
} | } | ||||
public void PrepareData() | public void PrepareData() | ||||
@@ -159,29 +172,8 @@ namespace TensorFlowNET.Examples | |||||
} | } | ||||
} | } | ||||
public Graph ImportGraph() | |||||
{ | |||||
throw new NotImplementedException(); | |||||
} | |||||
public Graph BuildGraph() | |||||
{ | |||||
throw new NotImplementedException(); | |||||
} | |||||
public void Train(Session sess) | |||||
{ | |||||
throw new NotImplementedException(); | |||||
} | |||||
public void Predict(Session sess) | |||||
{ | |||||
throw new NotImplementedException(); | |||||
} | |||||
public void Test(Session sess) | |||||
{ | |||||
throw new NotImplementedException(); | |||||
} | |||||
public Graph BuildGraph() => throw new NotImplementedException(); | |||||
public void Train(Session sess) => throw new NotImplementedException(); | |||||
public void Test(Session sess) => throw new NotImplementedException(); | |||||
} | } | ||||
} | } |
@@ -28,7 +28,7 @@ namespace TensorFlowNET.Examples.Utility | |||||
var perm = np.random.permutation(y.shape[0]); | var perm = np.random.permutation(y.shape[0]); | ||||
np.random.shuffle(perm); | np.random.shuffle(perm); | ||||
return (train.data[perm], train.labels[perm]); | |||||
return (x[perm], y[perm]); | |||||
} | } | ||||
/// <summary> | /// <summary> | ||||
@@ -39,6 +39,7 @@ namespace TensorFlowNET.ExamplesTests | |||||
new InceptionArchGoogLeNet() { Enabled = true }.Run(); | new InceptionArchGoogLeNet() { Enabled = true }.Run(); | ||||
} | } | ||||
[Ignore] | |||||
[TestMethod] | [TestMethod] | ||||
public void KMeansClustering() | public void KMeansClustering() | ||||
{ | { | ||||
@@ -83,10 +84,12 @@ namespace TensorFlowNET.ExamplesTests | |||||
new NearestNeighbor() { Enabled = true, TrainSize = 500, ValidationSize = 100, TestSize = 100 }.Run(); | new NearestNeighbor() { Enabled = true, TrainSize = 500, ValidationSize = 100, TestSize = 100 }.Run(); | ||||
} | } | ||||
[Ignore] | |||||
[TestMethod] | [TestMethod] | ||||
public void WordCnnTextClassification() | public void WordCnnTextClassification() | ||||
=> new CnnTextClassification { Enabled = true, ModelName = "word_cnn", DataLimit =100 }.Run(); | => new CnnTextClassification { Enabled = true, ModelName = "word_cnn", DataLimit =100 }.Run(); | ||||
[Ignore] | |||||
[TestMethod] | [TestMethod] | ||||
public void CharCnnTextClassification() | public void CharCnnTextClassification() | ||||
=> new CnnTextClassification { Enabled = true, ModelName = "char_cnn", DataLimit = 100 }.Run(); | => new CnnTextClassification { Enabled = true, ModelName = "char_cnn", DataLimit = 100 }.Run(); | ||||