diff --git a/src/hardware/sign_translator/CMakeLists.txt b/src/hardware/sign_translator/CMakeLists.txt index f882fd107516a4059d5f2c4147a63cc394811232..a0be575069b281995e8ac82a11462694da1bdd30 100644 --- a/src/hardware/sign_translator/CMakeLists.txt +++ b/src/hardware/sign_translator/CMakeLists.txt @@ -18,14 +18,14 @@ pico_sdk_init() add_executable(${PROJECT_NAME} main.cpp - #sign_model.cpp + sign_model.cpp ) -#add_subdirectory(${CMAKE_CURRENT_LIST_DIR}/pico-tflmicro) +add_subdirectory(${CMAKE_CURRENT_LIST_DIR}/pico-tflmicro) target_link_libraries(${PROJECT_NAME} pico_stdlib - #pico-tflmicro + pico-tflmicro ) # Create a UF2 file for flashing the RP2040 diff --git a/src/hardware/sign_translator/main.cpp b/src/hardware/sign_translator/main.cpp index 04fd1b9c12642315dcae03dbac12640a6c3d4742..c250b7ca9c306352f622eb196d2d662752781982 100644 --- a/src/hardware/sign_translator/main.cpp +++ b/src/hardware/sign_translator/main.cpp @@ -1,39 +1,148 @@ #include "pico/stdlib.h" #include <stdio.h> -/* +#include "tensorflow/lite/micro/tflite_bridge/micro_error_reporter.h" #include "tensorflow/lite/micro/micro_interpreter.h" #include "tensorflow/lite/micro/micro_log.h" #include "tensorflow/lite/micro/micro_mutable_op_resolver.h" #include "tensorflow/lite/micro/system_setup.h" #include "tensorflow/lite/schema/schema_generated.h" -*/ -//#include "sign_model.h" -int main() +#include "sign_model.h" + +// TEST LETTERS +unsigned char letter_n[] = {178, 179, 180, 180, 180, 180, 180, 181, 180, 180, 180, 182, 182, 182, 183, 184, 181, 181, 182, 182, 181, 181, 181, 181, 180, 178, 177, 178, 179, 180, 180, 180, 180, 181, 182, 181, 180, 182, 183, 182, 180, 180, 178, 178, 187, 186, 184, 183, 180, 181, 182, 182, 181, 180, 178, 179, 180, 181, 181, 181, 182, 182, 181, 181, 181, 182, 181, 183, 194, 197, 178, 144, 138, 169, 167, 182, 183, 183, 184, 184, 182, 182, 180, 179, 180, 181, 181, 181, 182, 182, 181, 181, 182, 182, 181, 202, 213, 211, 197, 151, 107, 84, 115, 119, 185, 183, 183, 182, 182, 182, 180, 181, 181, 181, 181, 181, 181, 182, 183, 183, 181, 183, 183, 172, 175, 201, 203, 162, 115, 71, 98, 75, 153, 191, 181, 184, 182, 183, 183, 183, 181, 181, 181, 182, 183, 183, 182, 184, 184, 152, 170, 169, 147, 167, 193, 175, 127, 76, 111, 118, 133, 195, 183, 185, 184, 184, 183, 183, 180, 181, 183, 183, 183, 184, 180, 199, 200, 143, 145, 172, 176, 182, 176, 180, 154, 77, 111, 110, 125, 195, 185, 185, 185, 185, 183, 183, 182, 182, 183, 184, 184, 183, 182, 215, 201, 167, 143, 113, 152, 177, 170, 141, 106, 67, 59, 114, 174, 188, 187, 186, 185, 186, 185, 185, 181, 182, 182, 184, 182, 193, 154, 136, 183, 191, 169, 108, 53, 129, 174, 147, 123, 103, 79, 99, 196, 186, 187, 186, 186, 186, 186, 185, 180, 182, 182, 176, 196, 203, 137, 89, 113, 202, 182, 141, 53, 45, 100, 130, 156, 168, 143, 85, 131, 200, 185, 187, 187, 185, 185, 184, 181, 181, 180, 196, 206, 180, 131, 111, 71, 175, 194, 144, 103, 44, 44, 66, 180, 191, 177, 141, 83, 158, 195, 184, 185, 185, 185, 183, 182, 180, 191, 207, 172, 169, 144, 133, 67, 126, 203, 155, 137, 68, 54, 47, 131, 205, 191, 157, 113, 90, 184, 187, 184, 186, 185, 184, 182, 183, 198, 174, 137, 162, 157, 140, 89, 56, 182, 184, 157, 109, 42, 78, 148, 193, 193, 158, 134, 89, 145, 196, 184, 186, 186, 186, 181, 188, 203, 185, 148, 149, 170, 138, 127, 66, 77, 195, 173, 146, 90, 111, 206, 186, 174, 148, 134, 91, 140, 198, 186, 187, 187, 187, 180, 188, 197, 182, 163, 135, 152, 160, 157, 119, 36, 99, 187, 176, 164, 129, 194, 180, 158, 124, 107, 79, 158, 195, 187, 186, 187, 186, 183, 187, 200, 197, 179, 156, 127, 147, 164, 142, 121, 46, 151, 177, 163, 178, 184, 166, 148, 118, 86, 77, 179, 190, 187, 187, 187, 185, 174, 175, 201, 207, 193, 170, 155, 142, 146, 145, 160, 98, 177, 197, 190, 193, 177, 158, 138, 112, 80, 99, 197, 192, 192, 191, 189, 188, 102, 99, 191, 210, 200, 181, 165, 161, 162, 144, 117, 138, 197, 207, 207, 184, 171, 156, 131, 102, 76, 117, 179, 173, 177, 177, 179, 181, 87, 69, 159, 214, 201, 190, 175, 165, 170, 169, 140, 134, 185, 206, 202, 185, 158, 142, 123, 93, 82, 87, 93, 96, 96, 96, 96, 97, 92, 81, 117, 207, 196, 195, 190, 177, 170, 168, 158, 124, 151, 201, 193, 178, 156, 128, 108, 88, 81, 89, 82, 76, 77, 87, 116, 142, 90, 90, 85, 180, 190, 190, 193, 190, 177, 168, 156, 140, 125, 180, 181, 164, 146, 119, 98, 86, 77, 90, 108, 128, 156, 178, 190, 182, 89, 93, 82, 122, 194, 184, 193, 196, 182, 169, 153, 140, 127, 146, 168, 149, 125, 112, 97, 78, 83, 150, 187, 194, 190, 184, 187, 181, 90, 89, 92, 80, 157, 192, 189, 189, 173, 161, 148, 135, 125, 125, 143, 142, 127, 108, 92, 65, 138, 218, 195, 182, 175, 161, 163, 172, 90, 90, 91, 84, 95, 189, 185, 170, 158, 150, 142, 132, 113, 108, 129, 146, 134, 100, 80, 69, 191, 203, 189, 177, 153, 134, 130, 145, 90, 89, 88, 91, 77, 160, 195, 161, 142, 144, 139, 129, 112, 95, 132, 157, 123, 89, 64, 116, 219, 194, 194, 177, 133, 106, 126, 136, 90, 90, 87, 93, 80, 128, 198, 167, 157, 157, 143, 125, 112, 95, 136, 155, 102, 84, 61, 177, 209, 190, 205, 188, 138, 92, 111, 136, 90, 91, 87, 92, 81, 112, 200, 178, 170, 170, 150, 131, 122, 97, 134, 144, 97, 74, 81, 207, 188, 184, 206, 206, 157, 98, 94, 127, 91, 92, 87, 91, 81, 111, 192, 186, 181, 175, 153, 141, 131, 92, 127, 138, 98, 63, 109, 210, 186, 180, 196, 213, 175, 107, 84, 107}; +unsigned char letter_b[] = {194, 196, 198, 200, 200, 202, 203, 202, 202, 203, 204, 204, 206, 206, 206, 206, 206, 206, 204, 205, 205, 206, 205, 204, 203, 205, 203, 203, 197, 201, 204, 203, 205, 205, 205, 206, 207, 209, 208, 208, 208, 210, 208, 209, 208, 210, 211, 208, 207, 207, 208, 208, 207, 205, 204, 204, 203, 206, 206, 207, 209, 210, 210, 211, 211, 212, 213, 214, 213, 212, 215, 213, 215, 203, 202, 215, 212, 212, 211, 210, 209, 207, 207, 206, 208, 211, 210, 213, 213, 214, 214, 215, 216, 218, 218, 217, 219, 219, 180, 206, 235, 197, 145, 224, 216, 215, 215, 214, 212, 212, 211, 211, 211, 215, 215, 218, 218, 217, 218, 219, 218, 221, 223, 220, 230, 233, 139, 199, 241, 182, 138, 222, 212, 222, 218, 217, 215, 215, 214, 213, 215, 218, 219, 222, 222, 222, 222, 225, 223, 224, 221, 211, 243, 218, 139, 212, 236, 158, 160, 221, 155, 204, 227, 220, 220, 219, 219, 218, 218, 220, 221, 223, 227, 227, 226, 228, 227, 232, 214, 165, 221, 196, 143, 231, 230, 143, 181, 233, 139, 183, 236, 223, 223, 222, 221, 221, 222, 223, 224, 228, 230, 229, 230, 230, 228, 243, 211, 147, 199, 192, 153, 242, 234, 152, 203, 235, 139, 184, 240, 226, 227, 225, 224, 224, 225, 227, 229, 231, 234, 234, 232, 235, 232, 245, 189, 148, 196, 182, 164, 233, 217, 150, 222, 230, 132, 190, 240, 230, 231, 229, 229, 228, 228, 229, 232, 234, 236, 237, 236, 237, 235, 252, 185, 159, 182, 165, 145, 225, 192, 146, 239, 231, 139, 204, 242, 236, 235, 233, 232, 231, 230, 232, 236, 236, 238, 237, 239, 240, 238, 252, 174, 153, 182, 175, 135, 243, 186, 163, 249, 214, 142, 218, 243, 238, 237, 237, 236, 235, 233, 236, 237, 239, 239, 240, 240, 241, 244, 255, 186, 139, 183, 177, 139, 247, 181, 179, 249, 201, 139, 232, 245, 240, 239, 238, 237, 236, 235, 239, 241, 242, 243, 244, 244, 242, 246, 255, 191, 124, 162, 144, 127, 219, 150, 209, 254, 202, 149, 246, 246, 244, 242, 241, 240, 238, 237, 239, 243, 245, 245, 246, 246, 244, 251, 255, 195, 152, 196, 212, 191, 219, 196, 182, 235, 189, 163, 255, 245, 246, 245, 245, 244, 241, 241, 243, 243, 245, 246, 248, 248, 246, 255, 254, 206, 174, 155, 215, 245, 237, 236, 170, 171, 171, 178, 255, 248, 249, 247, 246, 245, 244, 242, 245, 245, 246, 249, 250, 250, 250, 255, 240, 190, 159, 128, 137, 174, 200, 252, 228, 147, 111, 203, 255, 249, 251, 249, 248, 247, 245, 245, 246, 249, 250, 251, 253, 253, 253, 255, 243, 190, 147, 137, 142, 146, 192, 255, 255, 191, 104, 226, 255, 252, 253, 252, 252, 251, 248, 245, 248, 251, 253, 253, 255, 251, 255, 255, 237, 183, 153, 152, 159, 206, 232, 229, 254, 212, 131, 234, 255, 254, 253, 252, 252, 252, 252, 247, 249, 251, 254, 255, 255, 252, 255, 255, 233, 189, 153, 166, 170, 239, 255, 232, 208, 187, 130, 195, 255, 254, 255, 255, 254, 253, 253, 248, 249, 252, 255, 255, 255, 254, 255, 255, 236, 194, 169, 169, 200, 255, 255, 223, 195, 152, 114, 203, 255, 255, 255, 255, 255, 255, 253, 251, 252, 254, 255, 255, 255, 255, 255, 255, 236, 195, 183, 167, 220, 255, 255, 208, 177, 139, 110, 236, 255, 255, 255, 255, 255, 255, 254, 252, 254, 255, 255, 255, 255, 255, 255, 255, 236, 207, 193, 169, 217, 255, 246, 195, 163, 123, 135, 255, 255, 255, 255, 255, 255, 255, 255, 253, 255, 255, 255, 255, 255, 255, 255, 255, 238, 213, 206, 164, 221, 255, 224, 181, 148, 111, 202, 255, 255, 255, 255, 255, 255, 255, 255, 253, 255, 255, 255, 255, 255, 255, 255, 255, 242, 215, 205, 164, 231, 247, 212, 175, 131, 126, 255, 255, 255, 255, 255, 255, 255, 255, 255, 254, 255, 255, 255, 255, 255, 255, 255, 255, 243, 222, 192, 166, 223, 212, 193, 161, 113, 172, 255, 255, 255, 255, 255, 255, 255, 255, 255, 254, 255, 255, 255, 255, 255, 255, 255, 255, 255, 233, 188, 179, 211, 190, 180, 149, 112, 233, 255, 255, 255, 255, 255, 255, 255, 255, 255, 254, 255, 255, 255, 255, 255, 254, 255, 255, 255, 233, 196, 194, 198, 183, 169, 123, 167, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 254, 255, 255, 239, 241, 223, 193, 190, 175, 170, 135, 129, 250, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255}; +unsigned char letter_y[] = {161, 166, 171, 176, 178, 181, 183, 186, 186, 187, 188, 189, 189, 189, 190, 190, 189, 188, 188, 188, 187, 186, 185, 185, 184, 184, 181, 180, 162, 167, 173, 177, 178, 181, 184, 186, 187, 189, 191, 191, 191, 191, 192, 190, 190, 190, 190, 189, 188, 187, 185, 186, 186, 184, 182, 181, 164, 169, 173, 176, 183, 183, 185, 187, 188, 190, 191, 192, 192, 191, 192, 192, 190, 191, 192, 190, 189, 189, 187, 187, 186, 183, 183, 182, 165, 168, 185, 198, 165, 186, 187, 189, 190, 192, 192, 193, 193, 192, 194, 193, 192, 192, 192, 190, 190, 190, 189, 189, 187, 184, 185, 183, 168, 165, 204, 219, 138, 189, 189, 190, 191, 193, 194, 195, 195, 194, 195, 195, 194, 192, 192, 191, 191, 191, 190, 189, 188, 185, 186, 185, 169, 167, 207, 212, 132, 188, 191, 191, 193, 194, 196, 198, 198, 198, 197, 196, 195, 195, 194, 193, 192, 192, 191, 190, 190, 188, 186, 185, 171, 168, 206, 219, 130, 180, 194, 193, 195, 196, 197, 198, 199, 199, 198, 197, 197, 197, 195, 194, 194, 193, 193, 191, 190, 189, 188, 187, 172, 170, 201, 226, 140, 176, 196, 193, 196, 198, 198, 198, 199, 199, 199, 199, 200, 199, 197, 197, 195, 195, 194, 193, 192, 191, 190, 189, 173, 173, 196, 230, 144, 166, 200, 195, 198, 198, 200, 201, 199, 201, 203, 201, 200, 199, 198, 197, 196, 196, 195, 194, 193, 193, 191, 189, 173, 175, 193, 237, 165, 148, 198, 198, 198, 206, 202, 196, 214, 209, 190, 203, 200, 200, 201, 199, 198, 196, 195, 194, 194, 194, 193, 191, 174, 179, 190, 246, 193, 148, 230, 209, 183, 239, 205, 154, 227, 225, 155, 174, 211, 203, 202, 201, 200, 201, 199, 199, 195, 194, 193, 192, 175, 180, 188, 236, 200, 180, 255, 208, 190, 243, 208, 156, 220, 212, 168, 136, 202, 207, 204, 203, 200, 194, 188, 183, 197, 194, 194, 192, 176, 183, 185, 232, 220, 214, 255, 208, 189, 251, 200, 168, 237, 199, 157, 117, 176, 213, 203, 204, 180, 157, 138, 117, 176, 201, 195, 194, 178, 186, 185, 236, 242, 228, 255, 216, 173, 253, 189, 172, 236, 193, 135, 103, 167, 209, 203, 198, 158, 127, 131, 156, 189, 200, 197, 196, 179, 184, 193, 233, 235, 224, 254, 221, 164, 237, 191, 176, 226, 182, 110, 80, 161, 212, 202, 175, 136, 154, 201, 207, 202, 199, 198, 197, 180, 182, 204, 230, 204, 209, 235, 218, 159, 227, 197, 176, 222, 159, 92, 122, 177, 205, 166, 138, 146, 209, 207, 203, 203, 201, 199, 198, 182, 183, 212, 253, 190, 183, 218, 207, 152, 231, 189, 178, 217, 147, 179, 206, 193, 168, 129, 134, 201, 210, 206, 206, 206, 205, 202, 200, 183, 181, 218, 255, 206, 171, 208, 202, 165, 238, 167, 165, 221, 211, 223, 198, 171, 153, 123, 195, 216, 209, 209, 208, 207, 206, 204, 201, 182, 180, 220, 255, 219, 162, 201, 212, 197, 230, 153, 193, 246, 219, 201, 190, 155, 133, 175, 219, 209, 209, 208, 208, 207, 205, 203, 201, 183, 182, 220, 255, 222, 176, 192, 205, 191, 210, 221, 250, 234, 210, 196, 175, 137, 147, 217, 213, 212, 210, 210, 208, 206, 205, 204, 201, 183, 182, 219, 255, 229, 202, 186, 211, 250, 255, 255, 236, 219, 207, 188, 150, 128, 195, 218, 213, 213, 212, 212, 210, 208, 206, 206, 203, 183, 184, 209, 255, 241, 210, 199, 223, 255, 255, 255, 229, 207, 187, 169, 131, 174, 221, 214, 215, 214, 215, 212, 211, 210, 207, 207, 205, 182, 187, 196, 255, 244, 214, 207, 230, 255, 255, 240, 223, 193, 167, 141, 156, 221, 216, 215, 214, 214, 213, 210, 210, 210, 207, 207, 206, 184, 191, 200, 250, 231, 214, 209, 231, 254, 241, 220, 201, 178, 151, 144, 215, 225, 222, 223, 221, 220, 218, 216, 215, 214, 216, 212, 204, 157, 156, 163, 238, 224, 221, 217, 226, 241, 231, 202, 175, 160, 137, 145, 164, 158, 158, 158, 157, 156, 157, 157, 157, 157, 146, 150, 180, 132, 129, 124, 227, 233, 228, 225, 229, 236, 220, 183, 159, 148, 131, 125, 121, 120, 120, 119, 117, 116, 117, 118, 109, 104, 142, 195, 207, 139, 140, 127, 226, 252, 231, 233, 231, 226, 207, 172, 151, 138, 131, 133, 133, 132, 131, 130, 129, 127, 128, 126, 142, 199, 229, 210, 185, 139, 140, 124, 218, 255, 236, 243, 224, 212, 202, 175, 142, 130, 131, 130, 132, 132, 130, 130, 129, 129, 123, 159, 230, 230, 198, 196, 172}; + +// TENSORFLOW LITE GLOBALS +tflite::ErrorReporter* error_reporter; +const tflite::Model* model; +tflite::MicroInterpreter* interpreter; +TfLiteTensor* input; +TfLiteTensor* output; + +const int kTensorArenaSize = 136 * 1024; +uint8_t tensor_arena[kTensorArenaSize]; + +// FUNCTIONS PROTOTYPE +char get_letter_from_model(float* model_output); +void setup_tflite(); + +int main() +{ + stdio_init_all(); // INIT SERIAL + sleep_ms(5000); + + // --------SETUP TENSORFLOW LITE-------- + printf("TENSORFLOW LITE SETUP \n\n"); + setup_tflite(); + + // --------TEST THE MODEL-------- + printf("MODEL TEST \n\n"); + printf("LETTER N\n"); + for (size_t i = 0; i < 784; i++) + { + input->data.f[i] = letter_n[i]; + } + + if (kTfLiteOk != interpreter->Invoke()) { + TF_LITE_REPORT_ERROR(error_reporter, "Invoke failed."); + } + + printf("Model found %c !!\n\n", get_letter_from_model(output->data.f)); + + printf("LETTER B\n"); + for (size_t i = 0; i < 784; i++) + { + input->data.f[i] = letter_b[i]; + } + + if (kTfLiteOk != interpreter->Invoke()) { + TF_LITE_REPORT_ERROR(error_reporter, "Invoke failed."); + } + + printf("Model found %c !!\n\n", get_letter_from_model(output->data.f)); + + printf("LETTER Y\n"); + for (size_t i = 0; i < 784; i++) + { + input->data.f[i] = letter_y[i]; + } + + if (kTfLiteOk != interpreter->Invoke()) { + TF_LITE_REPORT_ERROR(error_reporter, "Invoke failed."); + } + + printf("Model found %c !!\n\n", get_letter_from_model(output->data.f)); + + printf("MODEL TEST FINISHED \n\n"); + while (true) + { + + } + return 0; +} + +void setup_tflite() { - // INIT SERIAL - stdio_init_all(); - - /* - tflite::InitializeTarget(); - - // Map the model into a usable data structure. This doesn't involve any - // copying or parsing, it's a very lightweight operation. - const tflite::Model* model = tflite::GetModel(sign_model); - if (model->version() != TFLITE_SCHEMA_VERSION) { - MicroPrintf( - "Model provided is schema version %d not equal " - "to supported version %d.", - model->version(), TFLITE_SCHEMA_VERSION); - } - */ - - while (true) - { - printf("FILS DE PUTE!\n"); - } - return 0; + tflite::InitializeTarget(); + + // Set up logging + static tflite::MicroErrorReporter micro_error_reporter; + error_reporter = µ_error_reporter; + + // Map the model into a usable data structure + model = tflite::GetModel(sign_model); + if (model->version() != TFLITE_SCHEMA_VERSION) + { + MicroPrintf( + "Model provided is schema version %d not equal " + "to supported version %d.", + model->version(), TFLITE_SCHEMA_VERSION); + return; + } + + // Pull in only the operation implementations we need. + static tflite::MicroMutableOpResolver<5> micro_op_resolver; + micro_op_resolver.AddFullyConnected(); + micro_op_resolver.AddConv2D(); + micro_op_resolver.AddMaxPool2D(); + micro_op_resolver.AddSoftmax(); + micro_op_resolver.AddReshape(); + + // Build an interpreter to run the model with. + static tflite::MicroInterpreter static_interpreter( + model, micro_op_resolver, tensor_arena, kTensorArenaSize); + interpreter = &static_interpreter; + + // Allocate memory from the tensor_arena for the model's tensors. + TfLiteStatus allocate_status = interpreter->AllocateTensors(); + if (allocate_status != kTfLiteOk) { + TF_LITE_REPORT_ERROR(error_reporter, "AllocateTensors() failed"); + return; + + } + + // Get model input/output handlers + input = interpreter->input(0); + output = interpreter->output(0); } +char get_letter_from_model(float* model_output) +{ + char ALPHABET[] = "ABCDEFGHIJKLMNOPQRSTUVWXY"; + float max = 0.0f; + int letter_index = 25; + + for (int i = 0; i < 25; i++) + { + if(model_output[i] > max) + { + max = model_output[i]; + letter_index = i; + } + } + return ALPHABET[letter_index]; +} \ No newline at end of file diff --git a/src/pc/requirements.txt b/src/pc/requirements.txt index 88a68c64b4c7a15a9031a99b72dc4b0f9ef5e762..ede0629cc3c37d22103a581d4043ce9f8f162109 100644 --- a/src/pc/requirements.txt +++ b/src/pc/requirements.txt @@ -1,5 +1,5 @@ numpy -tensorflow==2.15 +tensorflow matplotlib keras pandas \ No newline at end of file diff --git a/src/pc/sign_language_detector.ipynb b/src/pc/sign_language_detector.ipynb index 963f5417a6da6c9f9aec6014dcf1f5e387c4972f..83db7b981000f7feca07f8fb85a0ba8a22ed2cae 100644 --- a/src/pc/sign_language_detector.ipynb +++ b/src/pc/sign_language_detector.ipynb @@ -16,20 +16,17 @@ "name": "stderr", "output_type": "stream", "text": [ - "2024-05-14 13:32:24.001611: I external/local_tsl/tsl/cuda/cudart_stub.cc:31] Could not find cuda drivers on your machine, GPU will not be used.\n", - "2024-05-14 13:32:24.171262: E external/local_xla/xla/stream_executor/cuda/cuda_dnn.cc:9261] Unable to register cuDNN factory: Attempting to register factory for plugin cuDNN when one has already been registered\n", - "2024-05-14 13:32:24.171342: E external/local_xla/xla/stream_executor/cuda/cuda_fft.cc:607] Unable to register cuFFT factory: Attempting to register factory for plugin cuFFT when one has already been registered\n", - "2024-05-14 13:32:24.195332: E external/local_xla/xla/stream_executor/cuda/cuda_blas.cc:1515] Unable to register cuBLAS factory: Attempting to register factory for plugin cuBLAS when one has already been registered\n", - "2024-05-14 13:32:24.255202: I external/local_tsl/tsl/cuda/cudart_stub.cc:31] Could not find cuda drivers on your machine, GPU will not be used.\n", - "2024-05-14 13:32:24.256604: I tensorflow/core/platform/cpu_feature_guard.cc:182] This TensorFlow binary is optimized to use available CPU instructions in performance-critical operations.\n", + "2024-05-15 14:52:10.734042: I external/local_tsl/tsl/cuda/cudart_stub.cc:32] Could not find cuda drivers on your machine, GPU will not be used.\n", + "2024-05-15 14:52:10.739481: I external/local_tsl/tsl/cuda/cudart_stub.cc:32] Could not find cuda drivers on your machine, GPU will not be used.\n", + "2024-05-15 14:52:10.809443: I tensorflow/core/platform/cpu_feature_guard.cc:210] This TensorFlow binary is optimized to use available CPU instructions in performance-critical operations.\n", "To enable the following instructions: AVX2 FMA, in other operations, rebuild TensorFlow with the appropriate compiler flags.\n", - "2024-05-14 13:32:25.179775: W tensorflow/compiler/tf2tensorrt/utils/py_utils.cc:38] TF-TRT Warning: Could not find TensorRT\n" + "2024-05-15 14:52:11.932892: W tensorflow/compiler/tf2tensorrt/utils/py_utils.cc:38] TF-TRT Warning: Could not find TensorRT\n" ] } ], "source": [ "import numpy as np\n", - "import tensorflow as tf\n", + "import tensorflow as tf #==2.15\n", "import matplotlib.pyplot as plt\n", "import pandas as pd\n", "import random\n", @@ -46,7 +43,7 @@ }, { "cell_type": "code", - "execution_count": 2, + "execution_count": 3, "metadata": {}, "outputs": [], "source": [ @@ -75,29 +72,21 @@ }, { "cell_type": "code", - "execution_count": 3, + "execution_count": 21, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ - "Letter : V\n" + "Letter : Y\n", + "Index : 24\n", + "unsigned char img[] = {161, 166, 171, 176, 178, 181, 183, 186, 186, 187, 188, 189, 189, 189, 190, 190, 189, 188, 188, 188, 187, 186, 185, 185, 184, 184, 181, 180, 162, 167, 173, 177, 178, 181, 184, 186, 187, 189, 191, 191, 191, 191, 192, 190, 190, 190, 190, 189, 188, 187, 185, 186, 186, 184, 182, 181, 164, 169, 173, 176, 183, 183, 185, 187, 188, 190, 191, 192, 192, 191, 192, 192, 190, 191, 192, 190, 189, 189, 187, 187, 186, 183, 183, 182, 165, 168, 185, 198, 165, 186, 187, 189, 190, 192, 192, 193, 193, 192, 194, 193, 192, 192, 192, 190, 190, 190, 189, 189, 187, 184, 185, 183, 168, 165, 204, 219, 138, 189, 189, 190, 191, 193, 194, 195, 195, 194, 195, 195, 194, 192, 192, 191, 191, 191, 190, 189, 188, 185, 186, 185, 169, 167, 207, 212, 132, 188, 191, 191, 193, 194, 196, 198, 198, 198, 197, 196, 195, 195, 194, 193, 192, 192, 191, 190, 190, 188, 186, 185, 171, 168, 206, 219, 130, 180, 194, 193, 195, 196, 197, 198, 199, 199, 198, 197, 197, 197, 195, 194, 194, 193, 193, 191, 190, 189, 188, 187, 172, 170, 201, 226, 140, 176, 196, 193, 196, 198, 198, 198, 199, 199, 199, 199, 200, 199, 197, 197, 195, 195, 194, 193, 192, 191, 190, 189, 173, 173, 196, 230, 144, 166, 200, 195, 198, 198, 200, 201, 199, 201, 203, 201, 200, 199, 198, 197, 196, 196, 195, 194, 193, 193, 191, 189, 173, 175, 193, 237, 165, 148, 198, 198, 198, 206, 202, 196, 214, 209, 190, 203, 200, 200, 201, 199, 198, 196, 195, 194, 194, 194, 193, 191, 174, 179, 190, 246, 193, 148, 230, 209, 183, 239, 205, 154, 227, 225, 155, 174, 211, 203, 202, 201, 200, 201, 199, 199, 195, 194, 193, 192, 175, 180, 188, 236, 200, 180, 255, 208, 190, 243, 208, 156, 220, 212, 168, 136, 202, 207, 204, 203, 200, 194, 188, 183, 197, 194, 194, 192, 176, 183, 185, 232, 220, 214, 255, 208, 189, 251, 200, 168, 237, 199, 157, 117, 176, 213, 203, 204, 180, 157, 138, 117, 176, 201, 195, 194, 178, 186, 185, 236, 242, 228, 255, 216, 173, 253, 189, 172, 236, 193, 135, 103, 167, 209, 203, 198, 158, 127, 131, 156, 189, 200, 197, 196, 179, 184, 193, 233, 235, 224, 254, 221, 164, 237, 191, 176, 226, 182, 110, 80, 161, 212, 202, 175, 136, 154, 201, 207, 202, 199, 198, 197, 180, 182, 204, 230, 204, 209, 235, 218, 159, 227, 197, 176, 222, 159, 92, 122, 177, 205, 166, 138, 146, 209, 207, 203, 203, 201, 199, 198, 182, 183, 212, 253, 190, 183, 218, 207, 152, 231, 189, 178, 217, 147, 179, 206, 193, 168, 129, 134, 201, 210, 206, 206, 206, 205, 202, 200, 183, 181, 218, 255, 206, 171, 208, 202, 165, 238, 167, 165, 221, 211, 223, 198, 171, 153, 123, 195, 216, 209, 209, 208, 207, 206, 204, 201, 182, 180, 220, 255, 219, 162, 201, 212, 197, 230, 153, 193, 246, 219, 201, 190, 155, 133, 175, 219, 209, 209, 208, 208, 207, 205, 203, 201, 183, 182, 220, 255, 222, 176, 192, 205, 191, 210, 221, 250, 234, 210, 196, 175, 137, 147, 217, 213, 212, 210, 210, 208, 206, 205, 204, 201, 183, 182, 219, 255, 229, 202, 186, 211, 250, 255, 255, 236, 219, 207, 188, 150, 128, 195, 218, 213, 213, 212, 212, 210, 208, 206, 206, 203, 183, 184, 209, 255, 241, 210, 199, 223, 255, 255, 255, 229, 207, 187, 169, 131, 174, 221, 214, 215, 214, 215, 212, 211, 210, 207, 207, 205, 182, 187, 196, 255, 244, 214, 207, 230, 255, 255, 240, 223, 193, 167, 141, 156, 221, 216, 215, 214, 214, 213, 210, 210, 210, 207, 207, 206, 184, 191, 200, 250, 231, 214, 209, 231, 254, 241, 220, 201, 178, 151, 144, 215, 225, 222, 223, 221, 220, 218, 216, 215, 214, 216, 212, 204, 157, 156, 163, 238, 224, 221, 217, 226, 241, 231, 202, 175, 160, 137, 145, 164, 158, 158, 158, 157, 156, 157, 157, 157, 157, 146, 150, 180, 132, 129, 124, 227, 233, 228, 225, 229, 236, 220, 183, 159, 148, 131, 125, 121, 120, 120, 119, 117, 116, 117, 118, 109, 104, 142, 195, 207, 139, 140, 127, 226, 252, 231, 233, 231, 226, 207, 172, 151, 138, 131, 133, 133, 132, 131, 130, 129, 127, 128, 126, 142, 199, 229, 210, 185, 139, 140, 124, 218, 255, 236, 243, 224, 212, 202, 175, 142, 130, 131, 130, 132, 132, 130, 130, 129, 129, 123, 159, 230, 230, 198, 196, 172};\n" ] }, { "data": { - "text/plain": [ - "<matplotlib.image.AxesImage at 0x7fe0d789acd0>" - ] - }, - "execution_count": 3, - "metadata": {}, - "output_type": "execute_result" - }, - { - "data": { - "image/png": "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Rk8++aRqa2v1zjvvOFxtpJgvIPxPaWlp739PnTpVRUVFys/P19tvv62HHnrI4coQC+69997e/54yZYqmTp2qwsJCVVVVac6cOQ5XNjDKysq0b9++a+LvoJdzqeOwfPny3v+eMmWKcnJyNGfOHNXV1amwsNDvZfYp5n8FN2rUKCUmJl70Kpbm5mZlZ2c7WlVsGDFihG688UYdOHDA9VKcOX8OcH5cbPz48Ro1alRcnh8rVqzQe++9p48++iji41uys7PV1dWllpaWiO3j9Xy41HHoS1FRkSTF1PkQ8wUUDAY1ffp0bdu2rfe6np4ebdu2TcXFxQ5X5t7JkydVV1ennJwc10txpqCgQNnZ2RHnR1tbm3bt2nXNnx+HDx/W8ePH4+r88DxPK1as0KZNm/Thhx+qoKAg4uvTp09XUlJSxPlQW1urQ4cOxdX5cKXj0Je9e/dKUmydD65fBdEfb775phcKhbz169d7//rXv7zly5d7I0aM8JqamlwvzVc/+9nPvKqqKq++vt7729/+5pWUlHijRo3yjh496nppA+rEiRPep59+6n366aeeJO/FF1/0Pv30U+/gwYOe53ner3/9a2/EiBHeli1bvJqaGm/hwoVeQUGBd+rUKccrj67LHYcTJ054jz/+uLdjxw6vvr7e++CDD7xvf/vb3g033OCdPn3a9dKj5pFHHvHC4bBXVVXlNTY29l46Ojp6t3n44Ye9cePGeR9++KG3e/dur7i42CsuLna46ui70nE4cOCA9/zzz3u7d+/26uvrvS1btnjjx4/3Zs2a5XjlkQZFAXme573yyiveuHHjvGAw6M2cOdPbuXOn6yX57p577vFycnK8YDDojRkzxrvnnnu8AwcOuF7WgPvoo488SRddlixZ4nneuZdiP/30015WVpYXCoW8OXPmeLW1tW4XPQAudxw6Ojq8uXPneqNHj/aSkpK8/Px8b9myZXH3P2l93X5J3rp163q3OXXqlPeTn/zEGzlypJeSkuLdddddXmNjo7tFD4ArHYdDhw55s2bN8tLT071QKORdf/313s9//nOvtbXV7cIvwMcxAACciPm/AQEA4hMFBABwggICADhBAQEAnKCAAABOUEAAACcoIACAExQQAMAJCggA4AQFBABwggICADhBAQEAnPgvIerEOAFmAyIAAAAASUVORK5CYII=", + "image/png": "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", "text/plain": [ "<Figure size 640x480 with 1 Axes>" ] @@ -109,10 +98,19 @@ "source": [ "alphabet = \"ABCDEFGHIJKLMNOPQRSTUVWXYZ\"\n", "\n", - "rand_i = random.randint(1, train_data.shape[0])\n", - "img = train_data[rand_i]\n", - "print(f\"Letter : {alphabet[train_label[rand_i]]}\")\n", - "plt.imshow(img, cmap='gray')" + "rand_i = random.randint(1, test_data.shape[0])\n", + "img = test_data[rand_i]\n", + "print(f\"Letter : {alphabet[test_label[rand_i]]}\")\n", + "print(f\"Index : {test_label[rand_i]}\")\n", + "plt.imshow(img, cmap='gray')\n", + "\n", + "c_tab = \"unsigned char img[] = {\"\n", + "for i in range(img.shape[0]):\n", + " for j in range(img.shape[1]):\n", + " c_tab += str(img[i][j][0]) + \", \"\n", + "c_tab = c_tab[:-2] + \"}\"\n", + "c_tab += \";\"\n", + "print(c_tab)" ] }, { @@ -381,7 +379,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.11.8" + "version": "3.12.3" }, "orig_nbformat": 4 },