|
| 1 | +namespace Gradient.Samples { |
| 2 | + using System; |
| 3 | + using System.Drawing; |
| 4 | + using System.IO; |
| 5 | + using System.Linq; |
| 6 | + using System.Text; |
| 7 | + using numpy; |
| 8 | + using tensorflow; |
| 9 | + using tensorflow.keras; |
| 10 | + using tensorflow.keras.layers; |
| 11 | + |
| 12 | + static class CSharpOrNot |
| 13 | + { |
| 14 | + public static Model CreateModel(int classCount) { |
| 15 | + var activation = tf.keras.activations.elu_fn; |
| 16 | + const int filterCount = 8; |
| 17 | + int[] resNetFilters = { filterCount, filterCount, filterCount }; |
| 18 | + return new Sequential(new Layer[] { |
| 19 | + new Dropout(rate: 0.05), |
| 20 | + Conv2D.NewDyn(filters: filterCount, kernel_size: 5, padding: "same"), |
| 21 | + Activation.NewDyn(activation), |
| 22 | + new MaxPool2D(pool_size: 2), |
| 23 | + new ResNetBlock(kernelSize: 3, filters: resNetFilters, activation: activation), |
| 24 | + new ResNetBlock(kernelSize: 3, filters: resNetFilters, activation: activation), |
| 25 | + new ResNetBlock(kernelSize: 3, filters: resNetFilters, activation: activation), |
| 26 | + new ResNetBlock(kernelSize: 3, filters: resNetFilters, activation: activation), |
| 27 | + new MaxPool2D(), |
| 28 | + new ResNetBlock(kernelSize: 3, filters: resNetFilters, activation: activation), |
| 29 | + new ResNetBlock(kernelSize: 3, filters: resNetFilters, activation: activation), |
| 30 | + new MaxPool2D(), |
| 31 | + new ResNetBlock(kernelSize: 3, filters: resNetFilters, activation: activation), |
| 32 | + new ResNetBlock(kernelSize: 3, filters: resNetFilters, activation: activation), |
| 33 | + new AvgPool2D(pool_size: 2), |
| 34 | + new Flatten(), |
| 35 | + new Dense(units: classCount, activation: tf.nn.softmax_fn), |
| 36 | + }); |
| 37 | + } |
| 38 | + |
| 39 | + public const int Width = 64, Height = 64; |
| 40 | + public static readonly Size Size = new Size(Width, Height); |
| 41 | + // being opinionated here |
| 42 | + const string Tab = " "; |
| 43 | + const char Whitespace = '\u00FF'; |
| 44 | + public static readonly string[] IncludeExtensions = { |
| 45 | + ".cs", |
| 46 | + ".py", |
| 47 | + ".h", |
| 48 | + ".cc", |
| 49 | + ".c", |
| 50 | + ".tcl", |
| 51 | + ".java", |
| 52 | + ".sh", |
| 53 | + }; |
| 54 | + |
| 55 | + public static ndarray<float> GreyscaleImageBytesToNumPy(byte[] inputs, int imageCount, int width, int height) |
| 56 | + => (dynamic)inputs.Select(b => (float)b).ToArray().NumPyCopy() |
| 57 | + .reshape(new[] { imageCount, height, width, 1 }) / 255.0f; |
| 58 | + |
| 59 | + public static string[] ReadCode(string filePath) |
| 60 | + => File.ReadAllLines(filePath) |
| 61 | + .Select(line => line.Replace("\t", Tab)) |
| 62 | + .Select(line => { |
| 63 | + var result = new StringBuilder(line.Length); |
| 64 | + // replace non-ASCII characters with underscore |
| 65 | + // also make all whitespace stand out |
| 66 | + foreach (char c in line) { |
| 67 | + result.Append( |
| 68 | + c <= 32 ? Whitespace |
| 69 | + : c >= 255 ? '_' |
| 70 | + : c); |
| 71 | + } |
| 72 | + return result.ToString(); |
| 73 | + }) |
| 74 | + .ToArray(); |
| 75 | + |
| 76 | + /// <summary> |
| 77 | + /// Copies a rectangular block of text into a byte array |
| 78 | + /// </summary> |
| 79 | + public static void RenderTextBlockToGreyscaleBytes(string[] lines, |
| 80 | + Point startingPoint, Size size, |
| 81 | + byte[] destination) |
| 82 | + { |
| 83 | + if (size.IsEmpty) throw new ArgumentException(); |
| 84 | + if (destination.Length < size.Width * size.Height) throw new ArgumentException(); |
| 85 | + if (startingPoint.Y == lines.Length) { |
| 86 | + Array.Fill(destination, (byte)Whitespace); |
| 87 | + return; |
| 88 | + } |
| 89 | + |
| 90 | + for (int y = 0; y < size.Height; y++) { |
| 91 | + int sourceY = y + startingPoint.Y; |
| 92 | + int destOffset = y * size.Width; |
| 93 | + if (sourceY >= lines.Length) { |
| 94 | + Array.Fill(destination, (byte)255, |
| 95 | + startIndex: destOffset, |
| 96 | + count: size.Width*size.Height - destOffset); |
| 97 | + return; |
| 98 | + } |
| 99 | + |
| 100 | + for (int x = 0; x < size.Width; x++) { |
| 101 | + int sourceX = x + startingPoint.X; |
| 102 | + if (sourceX >= lines[sourceY].Length) { |
| 103 | + Array.Fill(destination, (byte)255, |
| 104 | + startIndex: destOffset, |
| 105 | + count: size.Width - x); |
| 106 | + break; |
| 107 | + } |
| 108 | + |
| 109 | + destination[destOffset] = (byte)lines[sourceY][sourceX]; |
| 110 | + destOffset++; |
| 111 | + } |
| 112 | + } |
| 113 | + } |
| 114 | + } |
| 115 | +} |
0 commit comments