You can not select more than 25 topics Topics must start with a chinese character,a letter or number, can include dashes ('-') and can be up to 35 characters long.

VdCnn.cs 6.2 kB

6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Text;
  5. using Tensorflow;
  6. namespace TensorFlowNET.Examples.TextClassification
  7. {
  8. public class VdCnn : Python
  9. {
  10. private int embedding_size;
  11. private int[] filter_sizes;
  12. private int[] num_filters;
  13. private int[] num_blocks;
  14. private float learning_rate;
  15. private IInitializer cnn_initializer;
  16. private IInitializer fc_initializer;
  17. private Tensor x;
  18. private Tensor y;
  19. private Tensor is_training;
  20. private RefVariable global_step;
  21. private RefVariable embeddings;
  22. private Tensor x_emb;
  23. private Tensor x_expanded;
  24. public VdCnn(int alphabet_size, int document_max_len, int num_class)
  25. {
  26. embedding_size = 16;
  27. filter_sizes = new int[] { 3, 3, 3, 3, 3 };
  28. num_filters = new int[] { 64, 64, 128, 256, 512 };
  29. num_blocks = new int[] { 2, 2, 2, 2 };
  30. learning_rate = 0.001f;
  31. cnn_initializer = tf.keras.initializers.he_normal();
  32. fc_initializer = tf.truncated_normal_initializer(stddev: 0.05f);
  33. x = tf.placeholder(tf.int32, new TensorShape(-1, document_max_len), name: "x");
  34. y = tf.placeholder(tf.int32, new TensorShape(-1), name: "y");
  35. is_training = tf.placeholder(tf.boolean, new TensorShape(), name: "is_training");
  36. global_step = tf.Variable(0, trainable: false);
  37. // Embedding Layer
  38. with(tf.name_scope("embedding"), delegate
  39. {
  40. var init_embeddings = tf.random_uniform(new int[] { alphabet_size, embedding_size }, -1.0f, 1.0f);
  41. embeddings = tf.get_variable("embeddings", initializer: init_embeddings);
  42. x_emb = tf.nn.embedding_lookup(embeddings, x);
  43. x_expanded = tf.expand_dims(x_emb, -1);
  44. });
  45. Tensor conv0 = null;
  46. Tensor conv1 = null;
  47. Tensor conv2 = null;
  48. Tensor conv3 = null;
  49. Tensor conv4 = null;
  50. Tensor h_flat = null;
  51. Tensor fc1_out = null;
  52. Tensor fc2_out = null;
  53. Tensor logits = null;
  54. Tensor predictions = null;
  55. // First Convolution Layer
  56. with(tf.variable_scope("conv-0"), delegate
  57. {
  58. conv0 = tf.layers.conv2d(x_expanded,
  59. filters: num_filters[0],
  60. kernel_size: new int[] { filter_sizes[0], embedding_size },
  61. kernel_initializer: cnn_initializer,
  62. activation: tf.nn.relu);
  63. conv0 = tf.transpose(conv0, new int[] { 0, 1, 3, 2 });
  64. });
  65. with(tf.name_scope("conv-block-1"), delegate {
  66. conv1 = conv_block(conv0, 1);
  67. });
  68. with(tf.name_scope("conv-block-2"), delegate {
  69. conv2 = conv_block(conv1, 2);
  70. });
  71. with(tf.name_scope("conv-block-3"), delegate {
  72. conv3 = conv_block(conv2, 3);
  73. });
  74. with(tf.name_scope("conv-block-4"), delegate
  75. {
  76. conv4 = conv_block(conv3, 4, max_pool: false);
  77. });
  78. // ============= k-max Pooling =============
  79. with(tf.name_scope("k-max-pooling"), delegate
  80. {
  81. var h = tf.transpose(tf.squeeze(conv4, new int[] { -1 }), new int[] { 0, 2, 1 });
  82. var top_k = tf.nn.top_k(h, k: 8, sorted: false)[0];
  83. h_flat = tf.reshape(top_k, new int[] { -1, 512 * 8 });
  84. });
  85. // ============= Fully Connected Layers =============
  86. with(tf.name_scope("fc-1"), scope =>
  87. {
  88. fc1_out = tf.layers.dense(h_flat, 2048, activation: tf.nn.relu, kernel_initializer: fc_initializer);
  89. });
  90. with(tf.name_scope("fc-2"), scope =>
  91. {
  92. fc2_out = tf.layers.dense(fc1_out, 2048, activation: tf.nn.relu, kernel_initializer: fc_initializer);
  93. });
  94. with(tf.name_scope("fc-3"), scope =>
  95. {
  96. logits = tf.layers.dense(fc2_out, num_class, activation: null, kernel_initializer: fc_initializer);
  97. predictions = tf.argmax(logits, -1, output_type: tf.int32);
  98. });
  99. // ============= Loss and Accuracy =============
  100. with(tf.name_scope("loss"), delegate
  101. {
  102. var y_one_hot = tf.one_hot(y, num_class);
  103. });
  104. }
  105. private Tensor conv_block(Tensor input, int i, bool max_pool = true)
  106. {
  107. return with(tf.variable_scope($"conv-block-{i}"), delegate
  108. {
  109. Tensor conv = null;
  110. // Two "conv-batch_norm-relu" layers.
  111. foreach (var j in Enumerable.Range(0, 2))
  112. {
  113. with(tf.variable_scope($"conv-{j}"), delegate
  114. {
  115. // convolution
  116. conv = tf.layers.conv2d(
  117. input,
  118. filters: num_filters[i],
  119. kernel_size: new int[] { filter_sizes[i], num_filters[i - 1] },
  120. kernel_initializer: cnn_initializer,
  121. activation: null);
  122. // batch normalization
  123. conv = tf.layers.batch_normalization(conv, training: is_training);
  124. // relu
  125. conv = tf.nn.relu.Activate(conv);
  126. conv = tf.transpose(conv, new int[] { 0, 1, 3, 2 });
  127. });
  128. }
  129. if (max_pool)
  130. {
  131. // Max pooling
  132. return tf.layers.max_pooling2d(
  133. conv,
  134. pool_size: new int[] { 3, 1 },
  135. strides: new int[] { 2, 1 },
  136. padding: "SAME");
  137. }
  138. else
  139. {
  140. return conv;
  141. }
  142. });
  143. }
  144. }
  145. }

tensorflow框架的.NET版本,提供了丰富的特性和API,可以借此很方便地在.NET平台下搭建深度学习训练与推理流程。