fragily-deep에서 Keeeras의 mnist 모형을 시도했습니다.

개시하다


https://zenn.dev/mattn/articles/e871dab58be002
이번에는 피자버즈처럼 간단한 예지만 성능도 좋고 이미지 데이터만큼 큰 입력 데이터를 처리하는 것도 어렵지 않다.관심 있는 사람이 도전해보는 게 어때요?
아무도 하기 싫어서 혼자 했어요.

일단 모델부터 할게요.


곳곳에 mnist의 학습과 HDF5 코드를 토해낸다.
4
import tensorflow as tf

mnist = tf.keras.datasets.mnist

(x_train, y_train), (x_test, y_test) = mnist.load_data()
x_train, x_test = x_train / 255.0, x_test / 255.0

model = tf.keras.models.Sequential([
  tf.keras.layers.Flatten(input_shape=(28, 28)),
  tf.keras.layers.Dense(128, activation='relu'),
  tf.keras.layers.Dropout(0.2),
  tf.keras.layers.Dense(10, activation='softmax')
])

model.compile(optimizer='adam',
              loss='sparse_categorical_crossentropy',
              metrics=['accuracy'])

model.fit(x_train, y_train, epochs=5)
model.save('mnist_model.h5')
또한 제목으로만 그림을 읽거나 조정할 수 있고 공용역의 라이브러리 STB를 사용하여 그림을 처리할 수 있다.
https://github.com/nothings/stb
4
#include <iostream>
#include <fdeep/fdeep.hpp>
#define STB_IMAGE_IMPLEMENTATION
#define STB_IMAGE_RESIZE_IMPLEMENTATION
#include <stb/stb_image.h>
#include <stb/stb_image_resize.h>

int
main(int argc, char *argv[]) {
  const auto model = fdeep::load_model("mnist_model.json", true, fdeep::dev_null_logger);

  for (auto i = 1; i < argc; i++) {
    const char* filename = argv[i];
    int x = 0, y = 0, n = 0;
    float* img_data = stbi_loadf(filename, &x, &y, &n, STBI_grey);
    float* resized_image = (float*)std::malloc(28 * 28 * sizeof(float));
    stbir_resize_float(img_data, x, y, 0, resized_image, 28, 28, 0, 1); 

    const auto result = model.predict(
        {fdeep::tensor(fdeep::tensor_shape(
              static_cast<std::size_t>(28),
              static_cast<std::size_t>(28)),
        std::vector<float>(resized_image, resized_image+28*28*1))});
    //std::cout << fdeep::show_tensors(result) << std::endl;
    auto v = result[0].to_vector();
    auto it = std::max_element(v.begin(), v.end());
    std::cout << std::distance(v.begin(), it) << std::endl;

    stbi_image_free(img_data);
    stbi_image_free(resized_image);
  }
}
기본적으로 Makefile도
SRCS = \
	mnist.cxx

OBJS = $(subst .cxx,.o,$(SRCS))

CXX = clang++
CXXFLAGS = -std=c++20 \
	-I c:/dev/frugally-deep/include \
	-I c:/dev/FunctionalPlus/include \
	-I c:/dev/nlohmann_json/include \
	-I c:/msys64/mingw64/include/eigen3
LIBS = 
TARGET = mnist
ifeq ($(OS),Windows_NT)
TARGET := $(TARGET).exe
endif

.SUFFIXES: .cxx .o

all : $(TARGET)

$(TARGET) : $(OBJS)
	$(CXX) -o $@ $(OBJS) $(LIBS)

.cxx.o :
	$(CXX) -c $(CXXFLAGS) -I. $< -o $@

clean :
	rm -f *.o $(TARGET)

한번 해보세요.


먹는 그림은 이런 느낌이에요.

명령 매개변수에 이미지 파일이 있습니다.

느낌이 좋다.그나저나 AMD Ryzen5의 노트북에서는 초간 200장 정도의 이미지를 추정할 수 있다.

끝말


느낌이 좋다.성능이 좋다는 걸 알았으니 틈틈이 OpenCV로 촬영한 이미지를 실시간으로 추론하는 샘플로 써보는 것도 재밌을 것 같다.관심 있으신 분 말씀하세요.(직접 만든 로고)

좋은 웹페이지 즐겨찾기