【论文复现】Learning I/O Access Patterns to Improve Prefetching in SSDs 系列 1

news2024/12/26 21:52:55

文章目录

  • 前言
  • 数据集准备
  • 数据初探
  • 数据处理
  • 分配标签
  • 抽取有效列并搭建模型训练
  • 失败分析


前言

LSTM完成ssd I/的预取
ref:

  1. git地址: https://github.com/Chandranil2606/Learning-IO-Access-Patterns-to-improve-prefetching-in-SSDs-
  2. paper地址: https://people.ucsc.edu/~hlitz/papers/ecml2020.pdf
  3. 作者的presentation://www.youtube.com/watch?v=5NlatYYzfrY
  4. 作者的ppt我也没有,在3中可以在线观看

Learning I/O Access Patterns to Improve Prefetching in SSDs 2020年 美国 , University of California Santa Cruz 小论文 引用量有25个左右是SSD预取中最高的之一。作者说自己是头一个将深度学习的方式引入到ssd上的,而且称为了sota。

数据集准备

在这里插入图片描述
我是用vdi的数据集先试了一下:
数据集下载:http://server2.iotta.snia.org/downloaderinfos/new?trace_id=4934&type=file&sType=bwget&came_from=server2.iotta.snia.org
选取其中一天的csv:2016021612-LUN0.csv

数据初探

作者的git下有好多训练文件,最好用的是:Learning-IO-Access-Patterns-to-improve-prefetching-in-SSDs–main\NN Prefetcher\Multihead_model-(Batch_Generator) SYSTOR.ipynb
别问我是如何知道的,因为我先拿keras那个往下跑,跑到后面跑不下去了,好多写死的地方。
找到一个好的base能省很多事,吐槽一下,作者的代码风格是相当奔放的,可能企业和学术界的要求不一样吧.
但作者的pandas的使用是非常熟练的,可能nlp处理的是序列数据,pandas是基操。

先看官方对他数据的描述,数据是微软真实场景下跑出来的I/O request 序列

import pandas as pd
data_sample_path = r"F:\datasets\paper\0903-lstm-prefech\2016021612-LUN0.csv"
df = pd.read_csv(data_sample_path)
df.info()
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 2761269 entries, 0 to 2761268
Data columns (total 6 columns):
 #   Column     Dtype  
---  ------     -----  
 0   Timestamp  float64
 1   Response   float64
 2   IOType     object 
 3   LUN        int64  
 4   Offset     int64  
 5   Size       int64  
dtypes: float64(2), int64(3), object(1)
memory usage: 126.4+ MB

一共6列,2761269 行,解释如下:

3. I/O trace file format
The files are gzipped csv (comma-separated text) files. The fields in
the csv are:

Timestamp,Response,IOType,LUN,Offset,Size

  - Timestamp is the time the I/O was issued.
    The timestamp is given as a Unix time (seconds since 1/1/1970) with a fractional part. 
    Although the fractional part is nine digits, it is accurate only to the microsecond level; 
    please  ignore the nanosecond part.  
    If you need to process the timestamps in their original local timezone, it is UTC+0900 (JST).
    For example:
     > head 2016022219-LUN4.csv.gz  ← (Mon, 22 Feb 2016 19:00:00 JST)
       1456135200.013118000(Mon, 22 Feb 2016 10:00:00 GMT)       
  - Response is the time needed to complete the I/O.
  - IOType is "Read(R)", "Write(W)", or ""(blank).
    The blank indicates that there was no response message.
  - LUN is the LUN index (0,1,2,3,4, or 5).
  - Offset is the starting offset of the I/O in bytes from the start of
    the logical disk.
  - Size is the transfer size of the I/O request in bytes.

f分别是,请求发生的时刻,响应所用的时间段、IO类型(读、写、未知)、LUN 不重要、Offset 逻辑地址单元(LBA起始地址),size(IO请求大小)。
看下数据:

	Timestamp	Response	IOType	LUN	     Offset	    Size
0	1.455592e+09	0.006475	R	0	203468398592	32768
1	1.455592e+09	0.005276	R	0	4590576115200	4096
2	1.455592e+09	0.011025	R	0	4564742206976	65536
3	1.455592e+09	0.000170	W	0	3772221901312	4096
4	1.455592e+09	0.000167	W	0	3832104423424	16384

数据预处理前,先要观察和分析出数据特征,我直接出结论:

total_row=df.shape[0]
print("总行数:",total_row)
row_per_iotype = df['IOType'].value_counts()
print("分列统计:\n",row_per_iotype)
print("读写比:\n",round(row_per_iotype['R']/row_per_iotype['W'],2),":1")
总行数: 2761269
分列统计:
 R    2064219
W     697050
Name: IOType, dtype: int64
读写比: 2.96 :1
``
294行含有null,但都是响应时间列,不是我们论文所关注的列,不用理会。
````python
# 含null的值都在哪些列,【只是想计算有多少行含有至少一个空值的数据】
num_rows_with_null = df.isnull().any(axis=1).sum()
num_rows_with_null
``
看一下还有null的行数据,肉眼看过去都是Response为None,不是我们需要处理的数据,没问题。`
···
none_rows = df[df.isnull().any(axis=1)]
none_rows
···

![在这里插入图片描述](https://img-blog.csdnimg.cn/1063e346148843489a4bd67c85a4c7ff.png)

保险起见,把需要关注的列验证一下是否有None值,这几列都是false,没问题。
这里其实也是透剧了,只需要关注Timestape, IOType, offset,size. (其实这里还多说了,作者关注的更少。)

null_check = df[['Timestamp','IOType','Offset','Size']].isnull().any()
null_check
Timestamp    False
IOType       False
Offset       False
Size         False
dtype: bool
按时间序列排序,可以发现原始数据并不是完全严格按照时间序列排序,因此需要按时间序列处理,并重置index。
```python
df = df.sort_values(by=['Timestamp'])
df

在这里插入图片描述
按io request time 重新排序后重置index

df.reset_index(inplace=True, drop=True)

----------------------------分割线----------------------------------
至此,可以按照作者mentioned 2 个trick处理数据集了

数据处理

delta offset, 就是地址列占的空间太大,用delta的方式把它缩放,i/o size也是这样;

在这里插入图片描述
这是原论文的表述,一看就懂。但他其实代码实现要比描述的粗糙的多。某二位大牛老师在工程实践二结题的时候痛批我们的presentation【所谓做的好不如写得好,写得好不如吹的好】【我们不关注输出的呈现结果,更关注理论分析和原理架构的可行性】;
实际上,作者使用pandas的现成方法,LBA列是前项-后项, io_size 这里他做了合理数据裁剪,真实数据不是都是2^n, 可以用log函数计算成整数,也就是说现数据不齐。
作者的实现方式:

# 前项减去后项,最后一列没后项了,没的可减,所以产生了None,需要drop掉index为-1的列
df['ByteOffset_Delta'] = df['ByteOffset'] - df['ByteOffset'].shift(-1)
df = df.drop(df.index[-1])
# 看下前5行数据
df['ByteOffset_Delta'].head(5)

0   -4.361274e+12
1   -2.122391e+10
2   -4.609998e+09
3    4.357120e+12
4   -7.943132e+10
Name: ByteOffset_Delta, dtype: float64

统计一下ByteOffset_Delta还有多少中数值

from collections import Counter
x_offset_delta = Counter(df['ByteOffset_Delta'])
# 返回一个字典 {delta:counter},看一下top1000
x_offset_delta.most_common(10)
# offset 为-131072的为168291次,-4096.0的为167181次, 
[(-131072.0, 168290),
 (-4096.0, 167181),
 (-32768.0, 42603),
 (-16384.0, 30777),
 (-8192.0, 30407),
 (8192.0, 21644),
 (0.0, 19829),
 (-12288.0, 15873),
 (-65536.0, 13315),
 (4096.0, 12503)]

top 1000 的delta 能够覆盖多少,后面是拿top1000来做训练的

# top 1000 的delta 能够覆盖多少,后面是拿top1000来做训练的
vals_offset_delta = x_offset_delta.most_common(1000)
coverage = 0
for k,value in vals_offset_delta:
    coverage = coverage + value
print("Percentage Coverage:\n",coverage/len(df)*100)

Percentage Coverage:
27.432686722187054

能覆盖27%,若我们不做delta,直接看逻辑地址的top1000 覆盖了多少呢?

# 原始的类别
x_raw_offset = Counter(df['Offset'])
vals = {}
vals =  x_raw_offset.most_common(1000)
coverage = 0
for key,value in vals:
    coverage = coverage + value
print("Percentage Coverage Offset")
print("原始的类别:\n",(coverage/len(df))*100)

Percentage Coverage Offset
原始的类别:
6.0314319363422895

原始offset的top1000 才6%.

再看size的log处理

# 这是论文中的对i/o request size的请求大小的工程trick,用2^n 表示比较省空间。其实核心思想和offset 的 delta相似。
import math
df['size_ex'] = df['Size'].apply(lambda x:math.log2(x))

可是这里隐藏着一个秘密:
LBA delta 使用float存的,它不会减少任何显存或者内存空间,仅仅会减少文本label的空间,那玩意是当字符串存的。读文章的时候,我差点,就联想到内存/显存侧了。

看一下现在的数据:重点关注ByteOffset_Delta和size_ex 是工程trick处理后的结果。
在这里插入图片描述

到这里,以上代码讲数据预处理的所有前置工作完成。后面的工作:

  1. 将序列数据划分标签,ByteOffset_Delta 的top1000 划分为0-1000个类(I/O请求模式),不在top1000的划分为1001类(背景类)
  2. 要预测出未来n次请求的offset和size

在这里插入图片描述

这里就暴露了一个问题,size_ex 列 log处理后数据不齐。 作者真实的代码又用round() 裁剪成了整数,个人任务ceil的方式更合理,否则你只预测对了起始地址,但size小了,后面的那部分还需要等flash侧的io啊:

In [1]: round(12.3)
Out[1]: 12

In [2]: round(12.7)
Out[2]: 13
df['IOSize_log'] = np.log2(df['IOSize'])
df['IOSize_log_roundoff']= round(df['IOSize_log'])
print(len(Counter(df['IOSize'])))
print(len(Counter(df['IOSize_log'])))
print(len(Counter(df['IOSize_log_roundoff'])))
259
259
11

经过round之后,由259个数据变成了11个数据, 否则只是起到压缩空间的作用了。

按上面所有描述方式整理完数据集后:

	Timestamp	Response	IOType	LUN	ByteOffset	IOSize	ByteOffset_Delta	ByteOffset_Delta_class	ByteOffset_Delta_Class_1001	IOSize_log	IOSize_log_roundoff
0	1.455592e+09	0.011025	R	0	4564742206976	65536	-2.122391e+10	999999	0	16.000000	16.0
1	1.455592e+09	0.013890	R	0	4585966117376	4096	-4.609998e+09	999999	0	12.000000	12.0
2	1.455592e+09	0.005276	R	0	4590576115200	4096	4.357120e+12	999999	0	12.000000	12.0
3	1.455592e+09	0.010090	R	0	233456156672	32768	-7.943132e+10	999999	0	15.000000	15.0
4	1.455592e+09	0.005081	R	0	312887472128	4096	-3.461027e+12	999999	0	12.000000	12.0
...	...	...	...	...	...	...	...	...	...	...	...
2761262	1.455595e+09	0.000254	R	0	4556356860928	8192	-3.194880e+05	3529	107	13.000000	13.0
2761263	1.455595e+09	0.000255	R	0	4556357180416	8192	-1.884160e+05	6373	200	13.000000	13.0
2761264	1.455595e+09	0.000788	R	0	4556357368832	8192	-2.785280e+05	168	24	13.000000	13.0
2761265	1.455595e+09	0.000753	R	0	4556357647360	8192	-7.553299e+09	999999	0	13.000000	13.0
2761266	1.455595e+09	0.000818	R	0	4563910946304	122880	-2.539520e+05	322	35	16.906891	17.0

分配标签

IOsize 标签 11个

a = df['IOSize_log_roundoff'].unique().tolist()
size_id_map = {}
for i,id in enumerate(a): size_id_map[id] = i 
df['Size_Class'] = df['IOSize_log_roundoff'].map(lambda x: size_id_map[x])

delta LBA, 1001类;
它把不属于top1000的类,delta 都按999999来的,所以说很粗暴。不清楚为啥选这个数数字,但我私下验证过,这个delta 的确没在top 1000中。

from collections import Counter
x = Counter(df['ByteOffset_Delta_class'])
vals = {}
vals =  x.most_common(1000)
bo_list = []

for x in vals:
    bo_list.append(x[0])
        
count = 0
label_list = []

while (count < len(df)):
    x = df['ByteOffset_Delta_class'].iloc[count]
    if x in bo_list:
        label_list.append(x)
    else:
        label_list.append(999999)
    count= count + 1
    
ByteOffset_Delta_class_backup  = df['ByteOffset_Delta_class'] 
df['ByteOffset_Delta_class']  = label_list
print(len(Counter(df['ByteOffset_Delta_class'])))
    
a = df['ByteOffset_Delta_class'].unique().tolist()
bo_map = {}
for i,id in enumerate(a): bo_map[id] = i 
df['ByteOffset_Delta_Class_1001'] = df['ByteOffset_Delta_class'].map(lambda x: bo_map[x])
    
label_list = df['ByteOffset_Delta_Class_1001'] 
    
df['ByteOffset_Delta_Class_1001']  = label_list

看一看size_class 分的11个数字类。
在这里插入图片描述

抽取有效列并搭建模型训练

所以最有效的列就是 LBA delta 和 SIZE 列,作者确实也是这样抽取的。
其实timestamp,iotype 也有其存在的合理性,但我还是本着复现来做,这篇文章存疑的地方有一些。需要向作者大佬联系学习一下。
在这里插入图片描述

size_class 一共11类, byteoffsetdelta 一共1001类。

处理好的数据存放到文件,并作数据集train和test的切分:
0.75的比例切分,这个不能shuffle,因为是基于时间序列的。

# Split to train, validate and test
# Finding the value 75th percentile of TimeStamp
import math
training_pt_1 = math.floor((len(df)*0.75)) 

lba_train =df[:training_pt_1]['ByteOffset_Delta_Class_1001'].tolist()
lba_test = df[training_pt_1+1:]['ByteOffset_Delta_Class_1001'].tolist()
size_train = df[:training_pt_1]['Size_Class'].tolist()
size_test = df[training_pt_1+1:]['Size_Class'].tolist()

保存到文件:

data_path  = r'F:/datasets/paper/0903-lstm-prefech/handle_output/'
path_train  = os.path.join(data_path,"lba_train_2016021612.txt")


with open(path_train, 'w') as f:
    for item in lba_train:
        f.write("%s " % item)
        
path_test  = os.path.join(data_path,"lba_test_2016021612.txt")
with open(path_test, 'w') as f:
    for item in lba_test:
        f.write("%s " % item)

        
path_train  = os.path.join(data_path,"size_train_2016021612.txt")

with open(path_train, 'w') as f:
    for item in size_train:
        f.write("%s " % item)
        
path_test  = os.path.join(data_path,"size_test_2016021612.txt")
with open(path_test, 'w') as f:
    for item in size_test:
        f.write("%s " % item)

作者的网络结构:
在这里插入图片描述
分别将LBA delta 和 I/O size 编码 然后concatenate
concate的作用是堆叠拼接:
在这里插入图片描述
然后紧接着dropout, 说实话这个dropout个人有点莫名其妙,啥也没干呢,先dropout???
然后两个lstm的堆叠,两个output,就完了。

模型搭建:
作者用的是keras,可能是年代久远训练的时候会有bug
os.environ[“TF_FORCE_GPU_ALLOW_GROWTH”]=“true” # https://github.com/tensorflow/tensorflow/issues/33721
用这种方式解决。

# Two classification outputs
import keras

from keras.preprocessing import sequence
from keras.models import Sequential
from keras.layers import Dense, Embedding
from keras.layers import LSTM
from keras.datasets import imdb


from tensorflow.python.client import device_lib
import numpy as np
import csv
import pandas as pd
import sys
import os
import glob
import tensorflow as tf






from keras.layers import Dense, Input
from keras.models import Model
from keras.optimizers import Adam
from keras.layers import Concatenate, Dense, LSTM, Input, concatenate , Dot
from keras.callbacks import EarlyStopping
from keras.layers import Dense, Activation, Embedding, Dropout, TimeDistributed, Reshape




# no_docs = len(y_train_lba)
maxlen= 32

# from collections import Counter
# print(len(Counter(df['Size_Class'])))
# from collections import Counter
# print(len(Counter(df['ByteOffset_Delta_Class_1001'])))

# # define two sets of inputs
# inputA = Input(shape=(32,))
# inputB = Input(shape=(32,))
# # inputA = Sequential()
# # inputB = Sequential()
vocabulary_1 = len(Counter(df['ByteOffset_Delta_Class_1001']))
vocabulary_2 = len(Counter(df['Size_Class']))
hidden_size = 500

# input=Input(shape=(no_docs,maxlen),dtype='float64')
inputA=Input(shape=(maxlen,),dtype='float64')  
inputB=Input(shape=(maxlen,),dtype='float64') 


# the first branch operates on the first input
x = Embedding(input_dim=vocabulary_1,output_dim=hidden_size,input_length=maxlen)(inputA)
x = Model(inputs=inputA, outputs=x)

# # the second branch opreates on the second input
y = Embedding(input_dim=vocabulary_2,output_dim=hidden_size,input_length=maxlen)(inputB)
y = Model(inputs=inputB, outputs=y)
# combine the output of the two branches
combined = keras.layers.concatenate([x.output, y.output])

lstm1 = LSTM(hidden_size,return_sequences=True)(combined)
lstm2 = LSTM(hidden_size, return_sequences=True)(lstm1)

# create classification output
offset = keras.layers.wrappers.TimeDistributed(Dense(units=vocabulary_1, activation='softmax'), name='offset')(lstm2)
iosize = keras.layers.wrappers.TimeDistributed(Dense(units=vocabulary_2, activation='softmax'), name='iosize')(lstm2)




model =Model([inputA,inputB],[offset,iosize]) # combining all into a Keras model

model.compile(optimizer='rmsprop',
              loss={'offset': 'categorical_crossentropy', 'iosize': 'categorical_crossentropy'},
              loss_weights={'offset': 2., 'iosize': 1.5},
              metrics={ 'offset': 'categorical_accuracy', 'iosize': 'categorical_accuracy'})
model.summary()

两个输出都是用的交叉熵损失, loss weight是 2:1.5
模型输出:
在这里插入图片描述
数据集生成器,里面还用到了迭代器。vocabulary1,vocabulary2 应该是标签。看命名风格应该是词袋子或者词向量。这个等复习完lstm再做详解。

class KerasBatchGenerator(object):

    def __init__(self, data_1, data_2, num_steps, batch_size, vocabulary1,vocabulary2, skip_step=0):
        self.data_1 = data_1
        self.data_2 = data_2
        self.num_steps = num_steps
        self.batch_size = batch_size
        self.vocabulary1 = vocabulary1
        self.vocabulary2 = vocabulary2
        # this will track the progress of the batches sequentially through the
        # data set - once the data reaches the end of the data set it will reset
        # back to zero
        self.current_idx = 0
        # skip_step is the number of words which will be skipped before the next
        # batch is skimmed from the data set
        self.skip_step = skip_step

    def generate(self):
        x_lba = np.zeros((self.batch_size, self.num_steps))
        x_size = np.zeros((self.batch_size, self.num_steps))
        y_lba = np.zeros((self.batch_size, self.num_steps, self.vocabulary1))
        y_size = np.zeros((self.batch_size, self.num_steps, self.vocabulary2))
        while True:
            for i in range(self.batch_size):
                predict_ahead = 32
                if self.current_idx + self.num_steps >= len(self.data_1):
                    # reset the index back to the start of the data set
                    self.current_idx = 0
                x_lba[i, :] = self.data_1[self.current_idx:self.current_idx + self.num_steps]
                x_size[i, :] = self.data_2[self.current_idx:self.current_idx + self.num_steps]
                
                temp_y_lba = self.data_1[self.current_idx + predict_ahead:self.current_idx + self.num_steps + 1]
                temp_y_size = self.data_2[self.current_idx + predict_ahead:self.current_idx + self.num_steps + 1]
                # convert all of temp_y into a one hot representation
                y_lba[i, :, :] = to_categorical(temp_y_lba, num_classes=self.vocabulary1)
                y_size[i, :, :] = to_categorical(temp_y_size, num_classes=self.vocabulary2)
                self.current_idx += self.skip_step
                
            #yield (np.array(x_lba),np.array(x_size)), (np.array(y_lba),np.array(y_size))
            # print("--------",[x_lba, x_size],[y_lba, y_size],"\n")
            yield [x_lba, x_size],[y_lba, y_size]
#            yield [np.array(top_batch), np.array(bot_batch)], np.array(batch_labels)
#             print(x)
#             print(y)
#             yield x,y

数据集提取

num_steps = 32
batch_size = 32

train_data_generator = KerasBatchGenerator(train_data_lba,train_data_size, num_steps, batch_size, vocabulary_1,vocabulary_2,skip_step=0) 
test_data_generator = KerasBatchGenerator(test_data_lba,test_data_size, num_steps, batch_size, vocabulary_1, vocabulary_2, skip_step=0)

训练

import time
num_epochs = 1000
batch_size = 32
num_steps = 32
import os
os.environ["TF_FORCE_GPU_ALLOW_GROWTH"]="true"

monitor = EarlyStopping(monitor='val_loss', min_delta=1e-3, patience=3, verbose=1, mode='auto')
checkpointer = ModelCheckpoint(filepath=data_path + 'best_weights-4.hdf5', verbose=1,save_best_only=True)

print('Train...')
start_time = time.time()

# model.fit([X_train_lba,X_train_size],[y_train_lba,y_train_size],
#           verbose=1,epochs=1000,callbacks=[monitor,checkpointer])

valid_steps = len(train_data_lba)//(batch_size* 32)
train_steps = len(train_data_lba)//(batch_size *32)

model.fit_generator(train_data_generator.generate(),
                    train_steps,
                    num_epochs,
                    verbose=1,
                    validation_data=test_data_generator.generate(),
                    validation_steps= valid_steps,
                    callbacks=[checkpointer,monitor])




end_time = time.time()
print("--- %s seconds ---" % (end_time - start_time))

输出结果:

Train...
Epoch 1/1000
c:\ProgramData\Anaconda3\lib\site-packages\keras\engine\training.py:1915: UserWarning: `Model.fit_generator` is deprecated and will be removed in a future version. Please use `Model.fit`, which supports generators.
  warnings.warn('`Model.fit_generator` is deprecated and '
2022/2022 [==============================] - 62s 23ms/step - loss: 0.1504 - offset_loss: 0.0644 - iosize_loss: 0.0145 - offset_categorical_accuracy: 0.9960 - iosize_categorical_accuracy: 0.9960 - val_loss: 54.8147 - val_offset_loss: 15.7523 - val_iosize_loss: 15.5409 - val_offset_categorical_accuracy: 0.0000e+00 - val_iosize_categorical_accuracy: 0.0000e+00

Epoch 00001: val_loss improved from inf to 54.81469, saving model to F:/datasets/paper/0903-lstm-prefech/handle_output\best_weights-4.hdf5
Epoch 2/1000
2022/2022 [==============================] - 46s 23ms/step - loss: 4.1723e-07 - offset_loss: 1.1921e-07 - iosize_loss: 1.1921e-07 - offset_categorical_accuracy: 1.0000 - iosize_categorical_accuracy: 1.0000 - val_loss: 54.8147 - val_offset_loss: 15.7523 - val_iosize_loss: 15.5409 - val_offset_categorical_accuracy: 0.0000e+00 - val_iosize_categorical_accuracy: 0.0000e+00

Epoch 00002: val_loss did not improve from 54.81469
Epoch 3/1000
2022/2022 [==============================] - 47s 23ms/step - loss: 4.1723e-07 - offset_loss: 1.1921e-07 - iosize_loss: 1.1921e-07 - offset_categorical_accuracy: 1.0000 - iosize_categorical_accuracy: 1.0000 - val_loss: 54.8147 - val_offset_loss: 15.7523 - val_iosize_loss: 15.5409 - val_offset_categorical_accuracy: 0.0000e+00 - val_iosize_categorical_accuracy: 0.0000e+00

Epoch 00003: val_loss did not improve from 54.81469
Epoch 4/1000
2022/2022 [==============================] - 50s 25ms/step - loss: 4.1723e-07 - offset_loss: 1.1921e-07 - iosize_loss: 1.1921e-07 - offset_categorical_accuracy: 1.0000 - iosize_categorical_accuracy: 1.0000 - val_loss: 54.8147 - val_offset_loss: 15.7523 - val_iosize_loss: 15.5409 - val_offset_categorical_accuracy: 0.0000e+00 - val_iosize_categorical_accuracy: 0.0000e+00

Epoch 00004: val_loss did not improve from 54.81469
Epoch 00004: early stopping
--- 203.98740601539612 seconds ---

这是一次失败的复现,训练集上特别好,test集上不灵光。

失败分析

  1. 搭建的网络和论文中给的不符,没有dropout 层,所以在combined之后,添加这几行代码。论文给的参数是0.1, 其实也未必。
combined = keras.layers.concatenate([x.output, y.output])

layer = tf.keras.layers.Dropout(0.1, input_shape=combined.shape)
combined = layer(combined, training=True)

然后io LBA detla 就能很快预测准确,然而size没有什么变化而且epoch=4 的时候 就early stop了,val_loss就不动了。
2. 当我把文件:2016022216-LUN3.csv
的iotype只选择 read 的时候,

Train...
Epoch 1/1000
c:\ProgramData\Anaconda3\lib\site-packages\keras\engine\training.py:1915: UserWarning: `Model.fit_generator` is deprecated and will be removed in a future version. Please use `Model.fit`, which supports generators.
  warnings.warn('`Model.fit_generator` is deprecated and '
765/765 [==============================] - 22s 25ms/step - loss: 0.7252 - offset_loss: 0.1892 - iosize_loss: 0.0302 - offset_categorical_accuracy: 0.9825 - iosize_categorical_accuracy: 0.9906 - val_loss: 1.8265 - val_offset_loss: 0.3639 - val_iosize_loss: 0.0955 - val_offset_categorical_accuracy: 1.0000 - val_iosize_categorical_accuracy: 1.0000

Epoch 00001: val_loss improved from inf to 1.82645, saving model to F:/datasets/paper/0903-lstm-prefech/handle_output\best_weights-4.hdf5
Epoch 2/1000
765/765 [==============================] - 18s 23ms/step - loss: 1.6093e-06 - offset_loss: 1.1921e-07 - iosize_loss: 1.1921e-07 - offset_categorical_accuracy: 1.0000 - iosize_categorical_accuracy: 1.0000 - val_loss: 1.8258 - val_offset_loss: 0.3637 - val_iosize_loss: 0.0955 - val_offset_categorical_accuracy: 1.0000 - val_iosize_categorical_accuracy: 1.0000

Epoch 00002: val_loss improved from 1.82645 to 1.82580, saving model to F:/datasets/paper/0903-lstm-prefech/handle_output\best_weights-4.hdf5
Epoch 3/1000
765/765 [==============================] - 18s 24ms/step - loss: 1.6093e-06 - offset_loss: 1.1921e-07 - iosize_loss: 1.1921e-07 - offset_categorical_accuracy: 1.0000 - iosize_categorical_accuracy: 1.0000 - val_loss: 1.8262 - val_offset_loss: 0.3637 - val_iosize_loss: 0.0955 - val_offset_categorical_accuracy: 1.0000 - val_iosize_categorical_accuracy: 1.0000

Epoch 00003: val_loss did not improve from 1.82580
Epoch 4/1000
765/765 [==============================] - 18s 24ms/step - loss: 1.6093e-06 - offset_loss: 1.1921e-07 - iosize_loss: 1.1921e-07 - offset_categorical_accuracy: 1.0000 - iosize_categorical_accuracy: 1.0000 - val_loss: 1.8266 - val_offset_loss: 0.3637 - val_iosize_loss: 0.0956 - val_offset_categorical_accuracy: 1.0000 - val_iosize_categorical_accuracy: 1.0000

Epoch 00004: val_loss did not improve from 1.82580
Epoch 5/1000
765/765 [==============================] - 18s 24ms/step - loss: 1.6093e-06 - offset_loss: 1.1921e-07 - iosize_loss: 1.1921e-07 - offset_categorical_accuracy: 1.0000 - iosize_categorical_accuracy: 1.0000 - val_loss: 1.8261 - val_offset_loss: 0.3636 - val_iosize_loss: 0.0956 - val_offset_categorical_accuracy: 1.0000 - val_iosize_categorical_accuracy: 1.0000

Epoch 00005: val_loss did not improve from 1.82580
Epoch 00005: early stopping
--- 94.8677487373352 seconds ---

然后就两个都100%了,真神奇。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/972635.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

halo个人博客搭建及介绍

halo个人博客搭建及介绍 halo介绍 halo强大易用的开源建站工具&#xff0c;配合上丰富的模板与插件&#xff0c;帮助你构建你心中的理想站点。具体可以搜索下官网的搭建指南。 博客技术架构 后端 1.spring reactive ,响应式编程&#xff0c;代码风格简单及高并发队列优化相…

android studio cmake生成.a文件(静态库)及调用(c c++)静态库.a

第一步生成静态库.a文件&#xff1a; cmake 语法如何生成静态库&#xff0c;就不介绍了&#xff0c;比较简单&#xff0c;我下文列出的参考资料里面有详细介绍。 add_library(${CMAKE_PROJECT_NAME} STATICsrc/CalculStatic.cpp)这一步有坑&#xff0c;我刚开始的时候&#x…

数学建模之图论

目录 1 图的基本概念2 如何做图2.1 直接做图2.2 编程做图 3 权重邻接矩阵3.1 无向图3.2 有向图 4 Dijkstra 算法4.1 算法概述4.2 代码实现 5 Floyd 算法5.1 算法概述5.2 代码实现 6 思考题 1 图的基本概念 图论中的图&#xff08;Graph&#xff09;是由若干给定的点及连接两点的…

mkp勒索病毒的介绍和防范,勒索病毒解密,数据恢复

mkp勒索病毒是一种新兴的电脑病毒&#xff0c;它会对感染的电脑进行加密&#xff0c;并要求用户支付一定的赎金才能解锁。这种病毒已经引起了全球范围内的关注&#xff0c;因为它不仅具有高危害性&#xff0c;而且还有很强的传播能力。本文将对mkp勒索病毒进行详细介绍&#xf…

群辉NAS:J1900系统盘安装SATA固态硬盘方案【自留记录】

群辉NAS&#xff1a;J1900系统盘安装SATA固态硬盘方案 设备介绍&#xff1a; DSM版本&#xff1a;918 主板CPU&#xff1a;蜗牛星际J1900板 内存&#xff1a;8G DDR3 固态&#xff1a;移速SATA固态&#xff08;msata在win微桌面识别&#xff0c;群晖安装时候识别不到&#xf…

pdf用什么软件打开?介绍几种常用打开方法

pdf用什么软件打开&#xff1f;PDF是一种广泛使用的文件格式&#xff0c;由于其跨平台和易于共享的特点&#xff0c;它已成为许多人在日常工作和学习中使用的首选文件格式。但是&#xff0c;有时候我们可能会遇到一些问题&#xff0c;比如不知道用什么软件打开PDF文件&#xff…

Hadoop生态之hive

一 概述与特点 之所以把Hive放在Hadoop生态里面去写,是因为它本身依赖Hadoop。Hive是基于Hadoop的一个数据仓库工具,可以将结构化的数据文件映射为一张数据库表,并提供类 SQL 查询功能。 其本质是将 SQL 转换为 MapReduce/Spark 的任务进行运算,底层由 HDFS 来提供…

软件测试/测试开发丨Web自动化 PageObject设计模式

点此获取更多相关资料 本文为霍格沃兹测试开发学社学员学习笔记分享 原文链接&#xff1a;https://ceshiren.com/t/topic/27167 一、page object 模式简介 马丁福勒个人博客 selenium 官网 1.1、传统 UI 自动化的问题 无法适应 UI 频繁变化无法清晰表达业务用例场景大量的样…

微任务创建 -- queueMicrotask()

微任务创建方式&#xff1a; Promise.then(()>{})Mutation Observer()queueMicrotask() 本文主要介绍queueMicrotask()的使用。 queueMicrotask的使用 Window 或 Worker 接口的 queueMicrotask() 方法&#xff0c;将微任务加入队列以在控制返回浏览器的事件循环之前的安全…

Git 版本回退 超神步骤

Git 版本回退 一. 背景 多版本分支开发&#xff0c;合并版本问题太多&#xff0c;需要回滚到某次版本。我的git客服端工具是 sourcetree 二.操作步骤 2.1 切到当前需要回退版本的分支 2.2 右击需要具体某一个分支&#xff0c;这个分支就是你想切到的分支版本&#xff0c;具体…

正版软件 | CloudDrive 多云盘本地挂载管理工具

前言&#xff1a; CloudDrive 是一个强大的多云盘管理工具&#xff0c;提供一站式的多云盘解决方案&#xff0c;包括云盘本地挂载。旨在无缝集成多个云存储服务&#xff0c;统一整合到一个界面。轻松管理和访问所有云存储服务&#xff0c;无需在不同的应用程序和界面之间切换。…

虚拟现实vr元宇宙井下危险隐患排查模拟实训稳固企业生产

数字化时代&#xff0c;职业教育正面临着前所未有的挑战和机遇&#xff0c;元宇宙的兴起&#xff0c;借助元宇宙平台进行钻井虚拟教学实验&#xff0c;基于元宇宙数字空间搭建更丰富、逼真、安全、灵活的实验环境&#xff0c;成为石油行业教育创新的催化剂。 一、降低实验成本 …

Excel·VBA二维数组组合函数的应用实例

看到一个问题《关于#穷举#的问题&#xff0c;如何解决&#xff1f;(语言-开发语言)》&#xff0c;对同一个数据存在“是/否”2种状态&#xff0c;判断其是否参与计算&#xff0c;并输出一系列数据的“是/否”状态的结果 目录 方法1&#xff1a;二维数组组合函数结果 方法2&am…

树上钟同步

#include<cstdio> #include<cstring> #include<vector> using namespace std;const int N 2505; int ori[N], f[N]; vector<int> edge[N]; // 邻接表的简单实现形式void dfs(int u, int fa) {for (int v : edge[u]) {if (v fa) continue;dfs(v, u);f…

网络协议从入门到底层原理学习(一)—— 简介及基本概念

文章目录 网络协议从入门到底层原理学习&#xff08;一&#xff09;—— 简介及基本概念一、简介1、网络协议的定义2、网络协议组成要素3、广泛的网络协议类型网络通信协议网络安全协议网络管理协议 4、网络协议模型对比图 二、基本概念1、网络互连模型2、计算机之间的通信基础…

Prompt Tuning训练过程

目录 0. 入门 0.1. NLP发展的四个阶段&#xff1a; Prompt工程如此强大&#xff0c;我们还需要模型训练吗&#xff1f; - 知乎 Prompt learning系列之prompt engineering(二) 离散型prompt自动构建 Prompt learning系列之训练策略篇 - 知乎 ptuning v2 的 chatglm垂直领域训练记…

【zookeeper】zookeeper日常运维

本文将分享一些zookeeper在日常使用中一些维护经验。 zookeeper清理快照 脚本或者命令清理 zookeeper长时间运行&#xff0c;快照逐渐增多可能造成服务器磁盘被占满的情况&#xff0c;但我们不能贸然用rm命令删除快照文件&#xff0c;如果直接删完会导致丢失好多数据&#x…

【Yellowbrick】特征可视化分析

Yellowbrick特征可视化分析 ⭐Yellowbrick⭐特征分析可视化⭐Rank1D⭐Rank2D ⭐Yellowbrick Yellowbrick是一个用于可视化机器学习模型和评估性能的Python库。它提供了一系列高级可视化工具&#xff0c;帮助数据科学家和机器学习从业者更好地理解、调试和优化他们的模型。 它在…

【【STM32-29正点原子版本串口发送传输实验】

STM32-29正点原子版本串口发送传输实验 通过串口接收或发送一个字符 例程目的 开发板上我们接入的是实现异步通信的UART接口 USB转串口原理图 我们一步步分析 PA9是串口1 的发送引脚 PA10是串口1 的接受引脚 。因为我们现在只是用到异步收发器功能&#xff0c;所以我们现…

应用可视化流程设计,实现提质增效流程化办公!

如果想要实现提高办公效率的目的&#xff0c;显然采用传统的办公方式是无法实现的。如今&#xff0c;在低代码技术平台深入无纸化办公的当下&#xff0c;应用可视化流程设计软件&#xff0c;可以借助其灵活、易操作、可视化、轻量级等优势特点&#xff0c;助力广大用户实现流程…