我有一个用于二进制图像分类的凸网模型:猫/狗。
library(keras)
conv_base <- application_vgg16(
weights = "imagenet",
include_top = FALSE,
input_shape = c(150, 150, 3)
)
# Hyperparameter construction
model <- keras_model_sequential() %>%
conv_base %>%
layer_flatten() %>%
layer_dense(units = 256, activation = "relu") %>%
layer_dense(units = 1, activation = "sigmoid")
model %>% compile(
loss = "binary_crossentropy",
optimizer = optimizer_rmsprop(lr = 2e-5),
metrics = c("accuracy")
)
img <- image_load('test_image.jpg', target_size = c(150, 150))
x <- image_to_array(img)
x <- array_reshape(x, c(1, dim(x)))
preds_class <- model %>% predict_classes(x)
model %>% predict(x)
predict(x)
给出一个概率,让我们推断它是 猫或狗。
我只有两个类的训练数据:猫/狗。 有没有办法在compile()
或超参数构造中修改代码 这样它就吐出 3 个概率
- 猫
- 狗
- non_catdog
第三类是不属于第 1 类和第 2 类的所有内容(猫/狗) 设计超参数或编译以预测 2 (+1 其他)类数据的策略,其中包含 2 个类训练
我觉得你的问题可能出在网络的建设上:
# Hyperparameter construction
model <- keras_model_sequential() %>%
conv_base %>%
layer_flatten() %>%
layer_dense(units = 256, activation = "relu") %>%
layer_dense(units = 1, activation = "sigmoid")
您的最后一层使用 sigmoid 激活,将您的输出压缩到[0,1]
.我认为您所追求的是softmax
激活,因为您有超过 2 个类。
不完全确定keras
语法,但可能是大致如下:
model <- keras_model_sequential() %>%
conv_base %>%
layer_flatten() %>%
layer_dense(units = 256, activation = "relu") %>%
layer_dense(units = 3, activation = "softmax")
正如评论中所标记的 - 网络损失函数也需要更改。二元熵方程仅假设预测和观测的单个向量,而在此体系结构中并非如此。
model %>% compile(
loss = "categorical_crossentropy",
optimizer = optimizer_rmsprop(lr = 2e-5),
metrics = c("accuracy")
)
更新
您正在尝试捕获 3 个可能的输出。可能属于A类,B类或两者都不属于。标签向量应如下所示:
Class A = [1, 0, 0]
Class B = [0, 1, 0]
Class C (! A || B) = [0, 0, 1]
将类 C 指定为[0, 0]
似乎是合乎逻辑的,但给出"softmax"的工作方式是有问题的。每个训练案例都有一个属于每个类的概率。因此,A 类的训练示例可以给出属于 B 类的 30% 概率。类预测本质上是一种投票。
即我预测这个例子是A类,因为与其他类概率相比,它具有最高的概率。