周报—2023/8/13

摘要

本周的学习内容包括读一篇关于精准曝气的论文以及时序代码部分。在论文阅读上,根据阅读论文的结构分析自己的论文在对应部分需要写哪些内容。根据自己要写的内容,列出来一系列要解决的问题。在代码时间部分,学习了一个只考虑用历史负荷来预测未来负荷的例子。

This week’s study includes reading a paper on precision aeration and a section on timing codes. In the paper reading, according to the structure of the reading paper, analyze what content needs to be written in the corresponding part of the paper. Make a list of problems to solve based on what i am going to write. In the code time section, you learn an example that only considers historical loads to predict future loads.

文章阅读

题目:污水处理精准曝气智能控制方法研究

作者:吴桐

文章来源:知网:https://kns.cnki.net/kcms/detail/detail.aspx?filename=1022749339.nh&dbname=CMFDTEMP

选题分析:

切入点

  1. 水污染现状

  2. 目前水处理有哪些方法,分别概述优缺点,从而引出微生物处理法是主流技术

  3. 分析传统的曝气存在哪些缺陷—曝气风机消耗大,过量曝气没有变成溶解氧,氧气逃逸,能耗大

  4. 引出解决方法,基于机器学习构建数据驱动模型,拟合入水出水曲线,从而为优化溶解氧浓度设定提供方法。

国内外现状分析

智能控制曝气方式处理厂很少,仍然依赖人工经验设定。这段的核心是:污水处理过程操作变量的优化设定是实施过程优化控制的关键环节。

别人的研究分析:

以降低能耗作为目标的 单运行指标操作变量设定值优化算法:

  • Amand 等将氧传递系数作为控制对象,通 过线性规划算法对控制对象进行优化,在优化出水硝氮流量的同时降低 14%的曝气能耗。

  • Duzinkiewicz 等使用遗传算法优化曝气能耗,获得 BSM1 中 Unit5 的最优溶解氧的设定值,之后将模型预测控制作为控制器,实现溶解氧优化设定 值的跟踪控制,该方法可以实现曝气能耗的最小化

污水处理成分复杂,控制变量少,系统存在耦合,为实现节能降耗,考虑元素多。作者把污水处理控制问题设定为一个多目标、多变量、多约束、多冲突的优化问题。对于此类问题的求解,根据目标函数的形式,可以分为单目标操作变量设定值寻优算法和多目标操作变量设定值寻优算法。

多目标设定值寻优算法首先根据操作变量的重要程度,使用不同的权重将多个待优化的操作变量合并为一个目标函数,即可将多目标优化问题转化为单目标 优化问题:

  • Qiao 等将曝气能耗和出水水质作为优化目标,并使用权重系数表示曝 气能耗和出水水质的重要程度,使用自适应动态规划算法在系统动态运行中根据 工况条件,调节 BSM1 模型第五单元溶解氧浓度和第二单元中硝态氮浓度,该方法能够减低 5.3%的曝气能耗。

  • Vega 等将曝气能耗、泵送能耗和出水水质评价 作为优化目标,使用权重系数表示三者的重要程度,使用序列二次规划算法优化 溶解氧浓度和硝态氮浓度的设定值,并使用非线性模型预测控制方法跟踪优化后 的溶解氧浓度和硝态氮浓度设定值,仿真结果表明该在保证出水水质达标的前提 下,可以较大程度地降低曝气能耗

作者的研究思路:

  1. 使用 Simulink 建立 BSM1 基准仿真平台,使其能够准确的表达 BSM1 模 型中描述的生化反应过程和沉淀过程(模拟反应过程)

  2. 提出了一种基于案例推理的溶解氧优化 设定方法。使用出水水质评价作为目标函数,并添加能耗作 为惩罚项,完成目标函数的构建采用神经网络的方式建立预测模型,将当前入水, 出水关键指标和操作变量作为输入矩阵,预测未来两小时之后出水水质评价指标

  3. 提出了一 种基于 DDPG(Deep Deterministic Policy Gradient)的曝气风量控制算法,在 BSM1 模型中增加入水质均化池,以两个小时为步长,使用当前入水出水典型特征及曝 气风量构建污水处理的马氏决策过程,使用 DDPG 算法设计控制器,将典型特 征作为 DDPG 输入,曝气风量作为动作输出,在仿真环境交互数据中学习最优 的风量设定值。

绪论模块学习总结:

研究背景、意义部分:

看了几篇环境方向的论文,研究背景部分都差不多,做水的就总结水污染问题。主要的差异体现在研究意义上,比如这篇做精准曝气的论文,文章对现有问题的阐述主要集中在:溶解氧浓度受多种因素影响,单一曝气量的能耗太大,然后针对这个问题提出了在多因素影响下如何曝气能满足低能耗的需要。这点是可以借鉴的,因为我要做的DO智能控制解决的核心问题也是能耗。因此研究意义也集中在通过深度学习的DO控制降低曝气氧气逃逸,降低能耗。

创新点部分:

结构上,看过的一些论文有些论文创新点写在绪论,有些论文创新点写在总结部分。

这篇文章的创新点是在第五章阐述的:针对现有污水处理精准曝气的曝气量难以精准控制问题,设计了一 种精准曝气优化控制方法,采用粒子群优化算法并结合案例推理,在 BSM1 模型 中使用动态溶解氧,流量,组分作为输入,利用神经网络建立曝气模型,该模型 能够反映出相关变量,能耗和出水水质评价间的关系,之后使用粒子群算法优化 各个入水工况的溶解氧设定值并采用案例推理的方式输出当前工况下最优的操 作参数。

这部分的收获就是在我的要写的论文里面,创新点总结可以写一下几点:

  • 传感器监测设备入水各项指标,分析实时DO需求量(问题1:有传感器数据,但是这个在论文里面不知道怎么阐述数据怎么来的。问题2:训练数据的最优溶解氧量是根据BOD跟氨氮计算来的吗?)

  • 建立各项因素(主要是曝气量,曝气量决定DO含量)对最终出水效果的一个函数,确定最优DO时序使得效果达标且能耗最低

文章的深度学习部分分析:

这篇文章在深度学习模块上,主要是利用神经网络建立曝气模型,该模型 能够反映出相关变量,能耗和出水水质评价间的关系,之后使用粒子群算法优化 各个入水工况的溶解氧设定值并采用案例推理的方式输出当前工况下最优的操 作参数。

提出了一种基于 DDPG 算法的出水稳定控制方法。首先将曝气问题抽象成 为适合强化学习方法解决的形式,之后对出水指标稳定性控制方法进行了设计, 并在仿真环境中对得到的控制方法进行了性能测试。

这部分跟我要做的是完全不同的,比如这篇文章是使用 Simulink 建立的 BSM1 基准仿真平台。(1、在我的论文里面,设备模型该怎么搭建,要不要像师兄论文里那样使用流场模拟?)

模型学习:

考虑到后面要跑时序模型,这周用LSTM搭建时序模型预测。

数据来自网络LSTM课程:

def load_data(file_name):
    df = pd.read_csv('data/new_data/' + file_name, encoding='gbk')
    columns = df.columns
    df.fillna(df.mean(), inplace=True)
    return df


class MyDataset(Dataset):
    def __init__(self, data):
        self.data = data

    def __getitem__(self, item):
        return self.data[item]

    def __len__(self):
        return len(self.data)
    
    
def nn_seq_us(B):
    print('data processing...')
    dataset = load_data()
    # split
    train = dataset[:int(len(dataset) * 0.6)]
    val = dataset[int(len(dataset) * 0.6):int(len(dataset) * 0.8)]
    test = dataset[int(len(dataset) * 0.8):len(dataset)]
    m, n = np.max(train[train.columns[1]]), np.min(train[train.columns[1]])

    def process(data, batch_size, shuffle):
        load = data[data.columns[1]]
        load = load.tolist()
        data = data.values.tolist()
        load = (load - n) / (m - n)
        seq = []
        for i in range(len(data) - 24):
            train_seq = []
            train_label = []
            for j in range(i, i + 24):
                x = [load[j]]
                train_seq.append(x)
            # for c in range(2, 8):
            #     train_seq.append(data[i + 24][c])
            train_label.append(load[i + 24])
            train_seq = torch.FloatTensor(train_seq)
            train_label = torch.FloatTensor(train_label).view(-1)
            seq.append((train_seq, train_label))

        # print(seq[-1])
        seq = MyDataset(seq)
        seq = DataLoader(dataset=seq, batch_size=batch_size, shuffle=shuffle, num_workers=0, drop_last=True)

        return seq

    Dtr = process(train, B, True)
    Val = process(val, B, True)
    Dte = process(test, B, False)

    return Dtr, Val, Dte, m, n
LSTM模型:
class LSTM(nn.Module):
    def __init__(self, input_size, hidden_size, num_layers, output_size, batch_size):
        super().__init__()
        self.input_size = input_size
        self.hidden_size = hidden_size
        self.num_layers = num_layers
        self.output_size = output_size
        self.num_directions = 1 # 单向LSTM
        self.batch_size = batch_size
        self.lstm = nn.LSTM(self.input_size, self.hidden_size, self.num_layers, batch_first=True)
        self.linear = nn.Linear(self.hidden_size, self.output_size)

    def forward(self, input_seq):
        batch_size, seq_len = input_seq.shape[0], input_seq.shape[1]
        h_0 = torch.randn(self.num_directions * self.num_layers, self.batch_size, self.hidden_size).to(device)
        c_0 = torch.randn(self.num_directions * self.num_layers, self.batch_size, self.hidden_size).to(device)
        # output(batch_size, seq_len, num_directions * hidden_size)
        output, _ = self.lstm(input_seq, (h_0, c_0)) # output(5, 30, 64)
        pred = self.linear(output)  # (5, 30, 1)
        pred = pred[:, -1, :]  # (5, 1)
        return pred


训练:
def train(args, Dtr, Val, path):
    input_size, hidden_size, num_layers = args.input_size, args.hidden_size, args.num_layers
    output_size = args.output_size
    if args.bidirectional:
        model = BiLSTM(input_size, hidden_size, num_layers, output_size, batch_size=args.batch_size).to(device)
    else:
        model = LSTM(input_size, hidden_size, num_layers, output_size, batch_size=args.batch_size).to(device)

    loss_function = nn.MSELoss().to(device)
    if args.optimizer == 'adam':
        optimizer = torch.optim.Adam(model.parameters(), lr=args.lr,
                                     weight_decay=args.weight_decay)
    else:
        optimizer = torch.optim.SGD(model.parameters(), lr=args.lr,
                                    momentum=0.9, weight_decay=args.weight_decay)
    scheduler = StepLR(optimizer, step_size=args.step_size, gamma=args.gamma)
    # training
    min_epochs = 10
    best_model = None
    min_val_loss = 5
    for epoch in tqdm(range(args.epochs)):
        train_loss = []
        for (seq, label) in Dtr:
            seq = seq.to(device)
            label = label.to(device)
            y_pred = model(seq)
            loss = loss_function(y_pred, label)
            train_loss.append(loss.item())
            optimizer.zero_grad()
            loss.backward()
            optimizer.step()

        scheduler.step()
        # validation
        val_loss = get_val_loss(args, model, Val)
        if epoch > min_epochs and val_loss < min_val_loss:
            min_val_loss = val_loss
            best_model = copy.deepcopy(model)

        print('epoch {:03d} train_loss {:.8f} val_loss {:.8f}'.format(epoch, np.mean(train_loss), val_loss))
        model.train()

    state = {'models': best_model.state_dict()}
    torch.save(state, path)
测试
def test(args, Dte, path, m, n):
    pred = []
    y = []
    print('loading models...')
    input_size, hidden_size, num_layers = args.input_size, args.hidden_size, args.num_layers
    output_size = args.output_size
    if args.bidirectional:
        model = BiLSTM(input_size, hidden_size, num_layers, output_size, batch_size=args.batch_size).to(device)
    else:
        model = LSTM(input_size, hidden_size, num_layers, output_size, batch_size=args.batch_size).to(device)
    # models = LSTM(input_size, hidden_size, num_layers, output_size, batch_size=args.batch_size).to(device)
    model.load_state_dict(torch.load(path)['models'])
    model.eval()
    print('predicting...')
    for (seq, target) in tqdm(Dte):
        target = list(chain.from_iterable(target.data.tolist()))
        y.extend(target)
        seq = seq.to(device)
        with torch.no_grad():
            y_pred = model(seq)
            y_pred = list(chain.from_iterable(y_pred.data.tolist()))
            pred.extend(y_pred)

    y, pred = np.array(y), np.array(pred)
    y = (m - n) * y + n
    pred = (m - n) * pred + n
    print('mape:', get_mape(y, pred))
    # plot
    x = [i for i in range(1, 151)]
    x_smooth = np.linspace(np.min(x), np.max(x), 900)
    y_smooth = make_interp_spline(x, y[150:300])(x_smooth)
    plt.plot(x_smooth, y_smooth, c='green', marker='*', ms=1, alpha=0.75, label='true')

    y_smooth = make_interp_spline(x, pred[150:300])(x_smooth)
    plt.plot(x_smooth, y_smooth, c='red', marker='o', ms=1, alpha=0.75, label='pred')
    plt.grid(axis='y')
    plt.legend()
    plt.show()

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-UFql5QPh-1691931143125)(周报+a04707b2-0123-4e80-8d4a-07613cae5347/image.png)]

总结

每周论文一篇阅读完成度:100%
代码学习完成度:100%

在DO控制的相关论文学习过程中,总结了一下问题:

  • 相关做精准曝气的论文有一个模拟实际污水处理的一个模型来描述生化反应的过程。比如这周读的这篇用到了simulink搭建一个活性污泥一号模型ASM1,用微分方程描述整个反映过程。我思考的是我需不需要再去学这个simulink,然后搭建一个类似的仿真模型?还是直接参照师兄的做法,写某养殖场上的应用,在套用数据?这样子数据来源也说得清楚了

  • 论文的重点在控制DO上的话,论文还需要写那套设备的搭建过程吗?比如流场分析,最终确定设备模型。

  • 虽然有传感器数据,但是在论文中该怎么阐述数据来源,是否要写搭建了一个有各种传感器实时监测的设备,从而得到了数据?

下周的学习一个是找老师学习这几个问题,其次放在学习多变量的时序代码上。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值