Skip to content
This repository was archived by the owner on Sep 26, 2020. It is now read-only.

Commit d092450

Browse files
authored
Better test result viz (#162)
* Fix how the y-axis of datasets are loaded. Write the model_input image to a file. Currently works for the default selections all the way through. * Fix loss in default job * Cleanup * Fix plugin name
1 parent 7877834 commit d092450

File tree

9 files changed

+34
-14
lines changed

9 files changed

+34
-14
lines changed

plugin/src/main/kotlin/edu/wpi/axon/plugin/DatasetPlugins.kt

+3-6
Original file line numberDiff line numberDiff line change
@@ -10,11 +10,10 @@ object DatasetPlugins {
1010
)
1111

1212
val divideByTwoFiveFivePlugin = Plugin.Official(
13-
"Divide Elements by 255",
13+
"Divide Data Elements by 255",
1414
"""
1515
|def process_dataset(x, y):
1616
| newX = tf.cast(x / 255.0, tf.float32)
17-
| newY = tf.cast(y / 255.0, tf.float32)
1817
| return (newX, newY)
1918
""".trimMargin()
2019
)
@@ -24,9 +23,8 @@ object DatasetPlugins {
2423
"""
2524
|def process_dataset(x, y):
2625
| newX = tf.cast(x / 255.0, tf.float32)
27-
| newY = tf.cast(y / 255.0, tf.float32)
2826
| newX = newX[..., tf.newaxis]
29-
| newY = newY[..., tf.newaxis]
27+
| newY = tf.keras.utils.to_categorical(y)
3028
| return (newX, newY)
3129
""".trimMargin()
3230
)
@@ -36,11 +34,10 @@ object DatasetPlugins {
3634
"""
3735
|def process_dataset(x, y):
3836
| newX = tf.cast(x / 255.0, tf.float32)
39-
| newY = tf.cast(y / 255.0, tf.float32)
4037
| newX = newX[..., tf.newaxis]
4138
| newX = tf.image.resize_images(newX, (224, 224), method=tf.image.ResizeMethod.BILINEAR, align_corners=True)
4239
| newX = tf.image.grayscale_to_rgb(newX)
43-
| newY = newY[..., tf.newaxis]
40+
| newY = tf.keras.utils.to_categorical(y)
4441
| return (newX, newY)
4542
""".trimMargin()
4643
)

plugin/src/main/kotlin/edu/wpi/axon/plugin/LoadTestDataPlugins.kt

+1
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ object LoadTestDataPlugins {
3535
| x_test = x_test[:1]
3636
| x_test = tf.cast(x_test / 255, tf.float32)
3737
| x_test = x_test[..., tf.newaxis]
38+
| y_test = tf.keras.utils.to_categorical(y_test)
3839
| return (x_test, y_test[:1], 1)
3940
""".trimMargin()
4041
)

plugin/src/main/kotlin/edu/wpi/axon/plugin/ProcessTestOutputPlugins.kt

+12-5
Original file line numberDiff line numberDiff line change
@@ -2,18 +2,25 @@ package edu.wpi.axon.plugin
22

33
object ProcessTestOutputPlugins {
44

5-
val serializeModelOutputPlugin = Plugin.Official(
6-
"Serialize Model Output",
5+
val classifyImageModelOutputPlugin = Plugin.Official(
6+
"Classify Image",
77
"""
88
|def process_model_output(model_input, expected_output, model_output):
9-
| # import json
109
| import numpy as np
10+
|
1111
| with open("output/expected_output.txt", "w+") as f:
12-
| # json.dump(expected_output, f)
1312
| np.savetxt(f, expected_output)
13+
|
1414
| with open("output/model_output.txt", "w+") as f:
15-
| # json.dump(model_output, f)
1615
| np.savetxt(f, model_output)
16+
|
17+
| images = tf.image.encode_jpeg(tf.cast(model_input[0]*255, tf.uint8))
18+
| fwrite = tf.write_file(
19+
| tf.constant("output/model_input.jpeg"),
20+
| images
21+
| )
22+
| with tf.Session() as session:
23+
| session.run(fwrite)
1724
""".trimMargin()
1825
)
1926
}

tf-data-code/src/main/kotlin/edu/wpi/axon/tfdata/code/loss/DefaultLossToCode.kt

+1
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import edu.wpi.axon.tfdata.loss.Loss
55
class DefaultLossToCode : LossToCode {
66

77
override fun makeNewLoss(loss: Loss) = when (loss) {
8+
is Loss.CategoricalCrossentropy -> "tf.keras.losses.categorical_crossentropy"
89
is Loss.SparseCategoricalCrossentropy -> "tf.keras.losses.sparse_categorical_crossentropy"
910
is Loss.MeanSquaredError -> "tf.keras.losses.mean_squared_error"
1011
}

tf-data-code/src/test/kotlin/edu/wpi/axon/tfdata/code/loss/DefaultLossToCodeTest.kt

+4
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,10 @@ internal class DefaultLossToCodeTest {
2121
@JvmStatic
2222
@Suppress("unused")
2323
fun lossSource() = listOf(
24+
Arguments.of(
25+
Loss.CategoricalCrossentropy,
26+
"""tf.keras.losses.categorical_crossentropy"""
27+
),
2428
Arguments.of(
2529
Loss.SparseCategoricalCrossentropy,
2630
"""tf.keras.losses.sparse_categorical_crossentropy"""

tf-data/src/main/kotlin/edu/wpi/axon/tfdata/loss/Loss.kt

+3
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,9 @@ import kotlinx.serialization.json.JsonConfiguration
77
@Serializable
88
sealed class Loss {
99

10+
@Serializable
11+
object CategoricalCrossentropy : Loss()
12+
1013
@Serializable
1114
object SparseCategoricalCrossentropy : Loss()
1215

ui-javafx/src/main/kotlin/edu/wpi/axon/ui/main/FrontendKoinModules.kt

+2-2
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ import edu.wpi.axon.plugin.LoadTestDataPlugins.loadExampleDatasetPlugin
1919
import edu.wpi.axon.plugin.LocalPluginManager
2020
import edu.wpi.axon.plugin.Plugin
2121
import edu.wpi.axon.plugin.PluginManager
22-
import edu.wpi.axon.plugin.ProcessTestOutputPlugins.serializeModelOutputPlugin
22+
import edu.wpi.axon.plugin.ProcessTestOutputPlugins.classifyImageModelOutputPlugin
2323
import edu.wpi.axon.ui.JobLifecycleManager
2424
import edu.wpi.axon.ui.JobRunner
2525
import edu.wpi.axon.ui.ModelManager
@@ -122,7 +122,7 @@ fun defaultFrontendModule() = module {
122122
single(named(processTestOutputPluginManagerName)) {
123123
bindPluginManager(
124124
setOf(
125-
serializeModelOutputPlugin
125+
classifyImageModelOutputPlugin
126126
),
127127
"axon-process-test-output-plugins",
128128
"process_test_output_plugin_cache.json"

ui-javafx/src/main/kotlin/edu/wpi/axon/ui/view/jobeditor/LossFragment.kt

+7
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,13 @@ class LossFragment : Fragment() {
2020
println("Loaded with loss type: ${job.lossType.value}")
2121
println("Loaded with loss: ${job.userLoss.value}")
2222
model = when (val loss = job.userLoss.value) {
23+
is Loss.CategoricalCrossentropy -> {
24+
field {
25+
label("CategoricalCrossentropy has no data.")
26+
}
27+
object : ItemViewModel<Unit>() {}
28+
}
29+
2330
is Loss.SparseCategoricalCrossentropy -> {
2431
field {
2532
label("SparseCategoricalCrossentropy has no data.")

ui-javafx/src/main/kotlin/edu/wpi/axon/ui/view/joblist/JobList.kt

+1-1
Original file line numberDiff line numberDiff line change
@@ -135,7 +135,7 @@ class JobList : View() {
135135
userOldModelPath = modelSource,
136136
userDataset = Dataset.ExampleDataset.FashionMnist,
137137
userOptimizer = Optimizer.Adam(),
138-
userLoss = Loss.SparseCategoricalCrossentropy,
138+
userLoss = Loss.CategoricalCrossentropy,
139139
userMetrics = setOf("accuracy"),
140140
userEpochs = 1,
141141
userNewModel = modelManager.loadModel(modelSource),

0 commit comments

Comments
 (0)