- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我正在使用基于 Unet 的模型对生物医学图像执行图像分割。每个图像都是 224x224,我有四个类,包括背景类。每个掩码的大小为 (224x224x4),因此我的生成器创建了一批大小为 (16x224x224x4) 的 numpy 数组。我将掩码的值重新转换为 1 或 0,因此对于每个类,相关 channel 中都存在 1。图像也按 1/255 缩放。我在训练期间使用骰子分数作为性能指标,并使用 1-dice 分数作为损失函数。我似乎在训练期间获得了高达 0.89 的分数,但我发现当我在测试集上进行预测时,我总是在预测背景类。我只在几百张图像上训练了 10 个 epoch(尽管我确实可以访问更多),这可能会影响模型,但我原以为我仍然会得到其他类的预测,所以我假设主要问题是类(Class)不平衡。从在线查看 sample_weight 参数可能是答案,但我不确定我打算如何实现实际的重量部分?大概我需要使用层在模型中的某个点将权重应用于像素数组,但我不确定如何。任何帮助将非常感激?
class DataGenerator(keras.utils.Sequence):
def __init__(self, imgIds, maskIds, imagePath, maskPath, batchSize=16, imageSize = (224, 224, 3), nClasses=2, shuffle=False):
self.imgIds = imgIds
self.maskIds = maskIds
self.imagePath = imagePath
self.maskPath = maskPath
self.batchSize = batchSize
self.imageSize = imageSize
self.nClasses = nClasses
self.shuffle = shuffle
def __load__(self, imgName, maskName):
img = cv2.imread(os.path.join(self.imagePath,imgName))
img = cv2.resize(img, (self.imageSize[0], self.imageSize[1]))
mask = cv2.imread(os.path.join(self.maskPath,maskName))
mask = np.dstack((mask, np.zeros((4000, 4000))))
mask[:,:,3][mask[:,:,0]==0]=255
mask = mask.astype(np.bool)
mask = img_as_bool(resize(mask, (self.imageSize[0], self.imageSize[1])))
mask = mask.astype('uint8')
img = img/255.0
mask = mask
return (img, mask)
def __getitem__(self, index):
if(index+1)*self.batchSize > len(self.imgIds):
self.batchSize = len(self.imgIds) - index*self.batchSize
batchImgs = self.imgIds[self.batchSize*index:self.batchSize*(index+1)]
batchMasks = self.maskIds[self.batchSize*index:self.batchSize*(index+1)]
batchfiles = [self.__load__(imgFile, maskFile) for imgFile, maskFile in
zip(batchImgs, batchMasks)]
images, masks = zip(*batchfiles)
return np.array(list(images)), np.array(list(masks))
def __len__(self):
return int(np.ceil(len(self.imgIds)/self.batchSize))
class Unet():
def __init__(self, imgSize):
self.imgSize = imgSize
def convBlocks(self, x, filters, kernelSize=(3,3), padding='same', strides=1):
x = keras.layers.BatchNormalization()(x)
x = keras.layers.Activation('relu')(x)
x = keras.layers.Conv2D(filters, kernelSize, padding=padding, strides=strides)(x)
return x
def identity(self, x, xInput, f, padding='same', strides=1):
skip = keras.layers.Conv2D(f, kernel_size=(1, 1), padding=padding, strides=strides)(xInput)
skip = keras.layers.BatchNormalization()(skip)
output = keras.layers.Add()([skip, x])
return output
def residualBlock(self, xIn, f, stride):
res = self.convBlocks(xIn, f, strides=stride)
res = self.convBlocks(res, f, strides=1)
output = self.identity(res, xIn, f, strides=stride)
return output
def upSampling(self, x, xInput):
x = keras.layers.UpSampling2D((2,2))(x)
x = keras.layers.Concatenate()([x, xInput])
return x
def encoder(self, x, filters, kernelSize=(3,3), padding='same', strides=1):
e1 = keras.layers.Conv2D(filters[0], kernelSize, padding=padding, strides=strides)(x)
e1 = self.convBlocks(e1, filters[0])
shortcut = keras.layers.Conv2D(filters[0], kernel_size=(1, 1), padding=padding, strides=strides)(x)
shortcut = keras.layers.BatchNormalization()(shortcut)
e1Output = keras.layers.Add()([e1, shortcut])
e2 = self.residualBlock(e1Output, filters[1], stride=2)
e3 = self.residualBlock(e2, filters[2], stride=2)
e4 = self.residualBlock(e3, filters[3], stride=2)
e5 = self.residualBlock(e4, filters[4], stride=2)
return e1Output, e2, e3, e4, e5
def bridge(self, x, filters):
b1 = self.convBlocks(x, filters, strides=1)
b2 = self.convBlocks(b1, filters, strides=1)
return b2
def decoder(self, b2, e1, e2, e3, e4, filters, kernelSize=(3,3), padding='same', strides=1):
x = self.upSampling(b2, e4)
d1 = self.convBlocks(x, filters[4])
d1 = self.convBlocks(d1, filters[4])
d1 = self.identity(d1, x, filters[4])
x = self.upSampling(d1, e3)
d2 = self.convBlocks(x, filters[3])
d2 = self.convBlocks(d2, filters[3])
d2 = self.identity(d2, x, filters[3])
x = self.upSampling(d2, e2)
d3 = self.convBlocks(x, filters[2])
d3 = self.convBlocks(d3, filters[2])
d3 = self.identity(d3, x, filters[2])
x = self.upSampling(d3, e1)
d4 = self.convBlocks(x, filters[1])
d4 = self.convBlocks(d4, filters[1])
d4 = self.identity(d4, x, filters[1])
return d4
def ResUnet(self, filters = [16, 32, 64, 128, 256]):
inputs = keras.layers.Input((224, 224, 3))
e1, e2, e3, e4, e5 = self.encoder(inputs, filters)
b2 = self.bridge(e5, filters[4])
d4 = self.decoder(b2, e1, e2, e3, e4, filters)
x = keras.layers.Conv2D(4, (1, 1), padding='same', activation='softmax')(d4)
model = keras.models.Model(inputs, x)
return model
imagePath = 'output/t2'
maskPath = 'output/t1'
imgIds = glob.glob(os.path.join(imagePath, '*'))
maskIds = glob.glob(os.path.join(maskPath, '*'))
imgIds = [os.path.basename(f) for f in imgIds]
maskIds = [os.path.basename(f) for f in maskIds]
trainImgIds = imgIds[:300]
trainMaskIds = maskIds[:300]
validImgIds = imgIds[300:350]
validMaskIds = maskIds[300:350]
trainGenerator = DataGenerator(trainImgIds, trainMaskIds, imagePath, maskPath, **params)
validGenerator = DataGenerator(validImgIds, validMaskIds, imagePath, maskPath)
trainSteps = len(trainImgIds)//trainGenerator.batchSize
validSteps = len(validImgIds)//validGenerator.batchSize
unet = Unet(224)
model = unet.ResUnet()
model.summary()
adam = keras.optimizers.Adam()
model.compile(optimizer=adam, loss=dice_coef_loss, metrics=[dice_coef])
hist = model.fit_generator(trainGenerator, validation_data=validGenerator,
steps_per_epoch=trainSteps, validation_steps=validSteps,
verbose=1, epochs=6)
最佳答案
我正在使用 Keras
它不是特别是样本权重。
首先,您最好转换为灰度图像和
您需要重新设计问题架构,如下所示:
构建两个模型:
1. 检测和分割图像像素或感兴趣区域 (ROI) 的分割模型 - 无论类别类型如何,您都可以将其提取为补丁。
假设您的 ROI 是值为 1(正)的像素,那么值 0(负)的背景很可能是像素的主要类别,因此它是不平衡的数据,因此您需要使用损失函数来更多地惩罚假阴性而不是误报,比如balanced_cross_entropy:
def balanced_cross_entropy(beta):
def convert_to_logits(y_pred):
y_pred = tf.clip_by_value(y_pred, tf.keras.backend.epsilon(), 1 - tf.keras.backend.epsilon())
return tf.log(y_pred / (1 - y_pred))
def loss(y_true, y_pred):
y_pred = convert_to_logits(y_pred)
pos_weight = beta / (1 - beta)
loss = tf.nn.weighted_cross_entropy_with_logits(logits=y_pred, targets=y_true, pos_weight=pos_weight)
# or reduce_sum and/or axis=-1
return tf.reduce_mean(loss * (1 - beta))
return loss
model.compile(optimizer=Adam(), loss=balanced_cross_entropy(0.2), metrics=["accuracy"])
class_weights = {0: 0.1, 1: 0.1, 2: 0.8}
model.fit_generator(train_gen, class_weight=class_weights)
model = load_model(filePath,
custom_objects={'loss': balanced_cross_entropy(0.2)})
关于deep-learning - 使用 keras 对多类图像分割中的样本进行加权,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60253082/
实际上我只需要用JAVA编写一个简单的程序来将MySQL INSERTS行转换为CSV文件(每个mysql表等于一个CSV文件) 在JAVA中使用正则表达式是最好的解决方案吗? 我的主要问题是如何正确
我有一个 txt 文件,其格式为: Key:value Key:value Key:value ... 我想将所有键及其值放入我创建的 hashMap 中。如何让 FileReader(file) 或
已关闭。此问题不符合Stack Overflow guidelines 。目前不接受答案。 要求提供代码的问题必须表现出对所解决问题的最低限度的了解。包括尝试的解决方案、为什么它们不起作用以及预期结果
我每周都会从我的主机下载数据库的备份。它生成一个 .sql 文件,当前大小约为 800mb。此 .sql 文件包含 44 个表。 有什么方法可以通过某些软件将 .sql 文件与所有表分开,以便单独导出
在 iOS 4.0 及更高版本中,有没有一种方法可以在不将整个图像加载到内存的情况下对 CGImage 进行分割?我试图做的是*以编程方式*分割图像,以便在使用大图像的 CATiledLayer 应用
我的 .split() 函数有问题,我有以下字符串: var imageUrl = "Images\Products\randomImage.jpg"; 我想用字符“\”分割,但是,这种情况发生了:
是否可以使用正则表达式将字符串拆分两次?例如,假设我有字符串: example=email@address.com|fname|lname 如何拆分结果为: email@address.com,fna
我正在寻找一种在线程系统(主从)中使用数组的解决方案,它允许我通过用户输入在多个线程上划分矩阵的计算,并将其通过 1 个主线程引导到多个从属线程,这些从属线程计算矩阵的 1 个字段。 我尝试运用我的知
我建立了一个系统来分割包含手写符号的二值图像并对它们进行分类(专门用于音乐)。我知道有商业应用程序可以执行此操作,但这是我尝试将其作为一个项目从头开始。 为了简单起见,假设我的整个图像中有两个元素:
我正在尝试找到一种可接受的复杂性的有效方法 检测图像中的对象,以便将其与周围环境隔离 将该对象分割成它的子部分并标记它们,这样我就可以随意获取它们 我进入图像处理世界已经 3 周了,我已经阅读了很多算
我有一组3D 空间中的点。下图是一个示例: 我想把这些点变成一个面。我只知道点的 X、Y 和 Z 值。例如,查看下图,它显示了从 3D 空间中的点生成的人脸网格。 我在谷歌上搜索了很多,但我找到的是一
我有一个字符串 String placeStr="place1*place2*place3"我想获取包含 place1、place2、place3 的数组,如下所示: String[] places=
我在 Python 中有一个类似于 google.com 的字符串,我想将其分成两部分:google 和 .com。问题是我有一个 URL,例如 subdomain.google.com,我想将其拆分
朋友需要对一个pdf文件进行分割,在网上查了查发现这个pypdf2可以完成这些操作,所以就研究了下这个库,并做一些记录。首先pypdf2是python3版本的,在之前的2版本有一个对应pypdf库。
伙计们,这是一个难以解决的问题,因为它涉及很多硬件细节,所以我想把它放到 EE.SE,但它的主要重点是编程,所以我决定坚持在这里。 我最近怀旧(以及渴望回到 CPU 内在函数),所以我决定自制一个 8
给定 haskell 中的排序列表,我如何获得分段列表,其中连续数字位于同一列表中。例如,如果我有一个排序列表 [1,2,3,4,7,8,10,12,13,15] 结果将是 [[1,2,3 ,4],[
如果我添加三个分割 View ,如下图所示,第三个分割 View (称为 splitView-3)将自动为该分割 View 中的自定义 View 生成约束,例如 customview1 的 Heigh
关闭。此题需要details or clarity 。目前不接受答案。 想要改进这个问题吗?通过 editing this post 添加详细信息并澄清问题. 已关闭 6 年前。 Improve th
如何为馈送给映射器的文件的每一行提供相同文件的拆分? 基本上我想做的是 for each line in file-split { for each line in file{
带有Snappy压缩功能的ORC文件是否可拆分成条形? 据我所知,Snappy Compressed File是不可拆分的。 但我在博客中读到,快速压缩的文件可以在 strip 上拆分。 真的吗? 最
我是一名优秀的程序员,十分优秀!