私はtensorflowとセマンティックセグメンテーションに新しいです。
私はセマンティックsegmentaionのためにU-Netのを設計しています。各画像は、私が分類することを一つの目的を持っています。しかし、合計で、私は10個の異なるオブジェクトのイメージがあります。私は混乱しています、どのように私は私のマスク入力を準備することができますか?それはマルチラベルセグメンテーションとして、または唯一のクラスのために考慮されていますか?
私は私の入力は1つのホットエンコードに変換する必要がありますか?私はto_categorical使用する必要がありますか?それはここの場合なら、私はマルチクラス分割のためのexaplesを見つけることが、私は知りません。一つの画像で私が唯一の分類/検出するために、一つのオブジェクトを持っているので。
私は、入力のための私のコードとしてこれを使用してみました。しかし、私は私がやっていることは右であるかどうか、わかりません。
#Generation of batches of image and mask
class DataGen(keras.utils.Sequence):
def __init__(self, image_names, path, batch_size, image_size=128):
self.image_names = image_names
self.path = path
self.batch_size = batch_size
self.image_size = image_size
def __load__(self, image_name):
# Path
image_path = os.path.join(self.path, "images/aug_test", image_name) + ".png"
mask_path = os.path.join(self.path, "masks/aug_test",image_name) + ".png"
# Reading Image
image = cv2.imread(image_path, 1)
image = cv2.resize(image, (self.image_size, self.image_size))
# Reading Mask
mask = cv2.imread(mask_path, -1)
mask = cv2.resize(mask, (self.image_size, self.image_size))
## Normalizaing
image = image/255.0
mask = mask/255.0
return image, mask
def __getitem__(self, index):
if(index+1)*self.batch_size > len(self.image_names):
self.batch_size = len(self.image_names) - index*self.batch_size
image_batch = self.image_names[index*self.batch_size : (index+1)*self.batch_size]
image = []
mask = []
for image_name in image_batch:
_img, _mask = self.__load__(image_name)
image.append(_img)
mask.append(_mask)
#This is where I am defining my input
image = np.array(image)
mask = np.array(mask)
mask = tf.keras.utils.to_categorical(mask, num_classes=10, dtype='float32') #Is this true?
return image, mask
def __len__(self):
return int(np.ceil(len(self.image_names)/float(self.batch_size)))
これは本当ですか?それであれば、私は私の入力に変更すべきかを出力としてラベル/クラスを取得しますか?私は私のクラスに応じて、私のマスクのピクセルの値を変更する必要がありますか?
ここに私のU-Netのアーキテクチャがあります。
# Convolution and deconvolution Blocks
def down_scaling_block(x, filters, kernel_size=(3, 3), padding="same", strides=1):
conv = keras.layers.Conv2D(filters, kernel_size, padding=padding, strides=strides, activation="relu")(x)
conv = keras.layers.Conv2D(filters, kernel_size, padding=padding, strides=strides, activation="relu")(conv)
pool = keras.layers.MaxPool2D((2, 2), (2, 2))(conv)
return conv, pool
def up_scaling_block(x, skip, filters, kernel_size=(3, 3), padding="same", strides=1):
conv_t = keras.layers.UpSampling2D((2, 2))(x)
concat = keras.layers.Concatenate()([conv_t, skip])
conv = keras.layers.Conv2D(filters, kernel_size, padding=padding, strides=strides, activation="relu")(concat)
conv = keras.layers.Conv2D(filters, kernel_size, padding=padding, strides=strides, activation="relu")(conv)
return conv
def bottleneck(x, filters, kernel_size=(3, 3), padding="same", strides=1):
conv = keras.layers.Conv2D(filters, kernel_size, padding=padding, strides=strides, activation="relu")(x)
conv = keras.layers.Conv2D(filters, kernel_size, padding=padding, strides=strides, activation="relu")(conv)
return conv
def UNet():
filters = [16, 32, 64, 128, 256]
inputs = keras.layers.Input((image_size, image_size, 3))
'''inputs2 = keras.layers.Input((image_size, image_size, 1))
conv1_2, pool1_2 = down_scaling_block(inputs2, filters[0])'''
Input = inputs
conv1, pool1 = down_scaling_block(Input, filters[0])
conv2, pool2 = down_scaling_block(pool1, filters[1])
conv3, pool3 = down_scaling_block(pool2, filters[2])
'''conv3 = keras.layers.Conv2D(filters[2], kernel_size=(3,3), padding="same", strides=1, activation="relu")(pool2)
conv3 = keras.layers.Conv2D(filters[2], kernel_size=(3,3), padding="same", strides=1, activation="relu")(conv3)
drop3 = keras.layers.Dropout(0.5)(conv3)
pool3 = keras.layers.MaxPooling2D((2,2), (2,2))(drop3)'''
conv4, pool4 = down_scaling_block(pool3, filters[3])
bn = bottleneck(pool4, filters[4])
deConv1 = up_scaling_block(bn, conv4, filters[3]) #8 -> 16
deConv2 = up_scaling_block(deConv1, conv3, filters[2]) #16 -> 32
deConv3 = up_scaling_block(deConv2, conv2, filters[1]) #32 -> 64
deConv4 = up_scaling_block(deConv3, conv1, filters[0]) #64 -> 128
outputs = keras.layers.Conv2D(10, (1, 1), padding="same", activation="softmax")(deConv4)
model = keras.models.Model(inputs, outputs)
return model
model = UNet()
model.compile(optimizer='adam', loss="categorical_crossentropy", metrics=["acc"])
train_gen = DataGen(train_img, train_path, image_size=image_size, batch_size=batch_size)
valid_gen = DataGen(valid_img, train_path, image_size=image_size, batch_size=batch_size)
test_gen = DataGen(test_img, test_path, image_size=image_size, batch_size=batch_size)
train_steps = len(train_img)//batch_size
valid_steps = len(valid_img)//batch_size
model.fit_generator(train_gen, validation_data=valid_gen, steps_per_epoch=train_steps, validation_steps=valid_steps,
epochs=epochs)
私はきちんと私の質問を説明することを願っています。すべてのヘルプはにappriciated!
UPDATE:私はオブジェクトクラスごとにマスクの各画素の値を変更しました。画像私はオブジェクト番号2として分類するオブジェクトが含まれている場合(私は)マスクのアレイ全体が0(BG)及び2(オブジェクトが含まれています2にマスクピクセルの値を変更しているので、各オブジェクトについて、マスク)0と3,0と10などが含まれます
ここでは、第1の2値にマスクを変更した後の画素の値が1より大きい場合、私は(何のオブジェクト/クラスに応じて)1又は2又は3にそれを変更しません
それから私は私のコードに示すようにto_categoricalでone_hotするためにそれらを変換します。実行を訓練が、ネットワークには、何かを学ぶdoesntの。精度と損失は2つの値の間で揺れ続けます。ここに私のミスは何ですか?私はマスクを生成でミスを作っています(?ピクセルの値を変更)または関数to_categoricalで?
問題が見つかりました:マスクの作成中に、私はエラーを作った..私は.. heightxwidthとして画像を読み取るCV2、で画像を読んでいた私は幅x高さとして私の画像DIMENTIONを考慮した後、クラスに応じた画素値を用いてマスクを作成し..引き起こしました何かを学ぶことではないネットワークを問題となって...それは今働いてます。..
各画像は、私が分類することを一つの目的を持っています。しかし、合計で、私は10個の異なるオブジェクトのイメージがあります。私は混乱しています、どのように私は私のマスク入力を準備することができますか?それはマルチラベルセグメンテーションとして、または唯一のクラスのために考慮されていますか?
(すなわち: - 背景、1から0犬、2 -cats ...)あなたのデータセットは、N個の異なるラベルを持っている場合、あなたはあなたのイメージが唯一の種類のオブジェクトの含まれている場合でも、マルチクラスの問題を抱えています。
私は私の入力は1つのホットエンコードに変換する必要がありますか?私はto_categorical使用する必要がありますか?
はい、あなたはワンホットエンコードあなたのラベルする必要があります。to_categoricalを使用すると、ラベルのソース形式に沸きます。あなたはNクラスを持っているし、あなたのラベルがあると言う(高さ、幅、1)の各画素が範囲[0、N)の値を持っています、。その場合にはkeras.utils.to_categorical(ラベル、N)は、各ピクセルが0または1である。そして、あなたが255で分割する必要はありませんフロート(高さ、幅、N)のラベルを提供します。
あなたのソース形式が異なる場合は、同じ出力形式を取得するために、カスタム関数を使用する必要があります。
:このレポ(ない私の仕事)チェックアウトkeras-UNETを。小さなデータセット上のu-ネットを訓練するために2つの例を含んでフォルダノートPC。彼らは、マルチクラスではありませんが、あなた自身のデータセットを使用するように一歩一歩を行くことは容易です。ラベルをロードすることにより、スター:
im = Image.open(mask).resize((512,512))
im = to_categorical(im,NCLASSES)
このようなリシェイプと正規化:
x = np.asarray(imgs_np, dtype=np.float32)/255
y = np.asarray(masks_np, dtype=np.float32)
y = y.reshape(y.shape[0], y.shape[1], y.shape[2], NCLASSES)
x = x.reshape(x.shape[0], x.shape[1], x.shape[2], 3)
NCLASSESにモデルを適応させます
model = custom_unet(
input_shape,
use_batch_norm=False,
num_classes=NCLASSES,
filters=64,
dropout=0.2,
output_activation='softmax')
正しい損失を選択します。
from keras.losses import categorical_crossentropy
model.compile(
optimizer=SGD(lr=0.01, momentum=0.99),
loss='categorical_crossentropy',
metrics=[iou, iou_thresholded])
それが役に立てば幸い