Esempio n. 1
0
File: alfr.py Progetto: windxrz/DCFR
class ALFR(FairRepr):
    def __init__(self, config):
        super(ALFR, self).__init__("ALFR", config)

        self.encoder = MLP(
            [config["xdim"]] + config["encoder"] + [config["zdim"]], "relu"
        )
        self.prediction = MLP(
            [config["zdim"]] + config["prediction"] + [config["ydim"]],
            "relu",
        )
        self.audit = MLP([config["zdim"]] + config["audit"] + [config["sdim"]], "relu")

    def forward_y(self, x):
        z = self.forward_z(x)
        y = self.prediction(z)
        y = torch.sigmoid(y)
        return y

    def forward_s(self, x, f):
        z = self.forward_z(x)
        s = self.audit(z)
        s = torch.sigmoid(s)
        return s

    def forward_z(self, x):
        z = torch.nn.functional.relu(self.encoder(x))
        return z

    def forward(self, x):
        self.forward_y(x)

    def loss_prediction(self, x, y, w):
        y_pred = self.forward_y(x)
        loss = weighted_cross_entropy(w, y, y_pred)
        return loss

    def loss_audit(self, x, s, f, w):
        s_pred = self.forward_s(x, f)
        loss = weighted_cross_entropy(w, s, s_pred)
        return loss

    def predict_only(self):
        self.audit.freeze()
        self.prediction.activate()
        self.encoder.activate()

    def audit_only(self):
        self.audit.activate()
        self.prediction.freeze()
        self.encoder.freeze()

    def finetune_only(self):
        self.audit.freeze()
        self.prediction.activate()
        self.encoder.freeze()

    def predict_params(self):
        return list(self.prediction.parameters()) + list(self.encoder.parameters())

    def audit_params(self):
        return self.audit.parameters()

    def finetune_params(self):
        return self.prediction.parameters()
Esempio n. 2
0
class CFair(FairRepr):
    def __init__(self, config):
        super(CFair, self).__init__("CFAIR", config)
        self.encoder = MLP([config["xdim"]] + config["encoder"] +
                           [config["zdim"]], "relu")
        self.prediction = MLP(
            [config["zdim"]] + config["prediction"] + [config["ydim"]],
            "relu",
        )
        self.audit1 = MLP([config["zdim"]] + config["audit"] +
                          [config["sdim"]], "relu")
        self.audit2 = MLP([config["zdim"]] + config["audit"] +
                          [config["sdim"]], "relu")

    def forward_y(self, x):
        z = self.forward_z(x)
        y = self.prediction(z)
        y = torch.sigmoid(y)
        return y

    def forward_s(self, x, f):
        z = self.forward_z(x)
        s = self.audit1(z) * f + self.audit2(z) * (1 - f)
        s = torch.sigmoid(s)
        return s

    def forward_z(self, x):
        z = torch.nn.functional.relu(self.encoder(x))
        return z

    def forward(self, x):
        self.forward_y(x)

    def loss_prediction(self, x, y, w):
        y_pred = self.forward_y(x)
        loss = weighted_cross_entropy(w, y, y_pred)
        return loss

    def loss_audit(self, x, s, f, w):
        s_pred = self.forward_s(x, f)
        loss = weighted_cross_entropy(w, s, s_pred)
        return loss

    def weight_pred(self, df_old):
        df = df_old.copy()
        df["w"] = 0
        res = df.groupby("result").count()["w"].to_dict()
        df["w"] = 1 / df["result"].apply(lambda x: res[x]) / 2
        res = torch.from_numpy(df["w"].values).view(-1, 1)
        return res

    def weight_audit(self, df_old, s, f):
        df = df_old.copy()
        df["w"] = 0
        for ss in range(2):
            for y in range(2):
                amount = df.loc[(df[s] == ss) & (df["result"] == y)].shape[0]
                df.loc[(df[s] == ss) & (df["result"] == y),
                       "w"] = 1.0 / amount / 4
        res = torch.from_numpy(df["w"].values).view(-1, 1)
        return res

    def predict_only(self):
        self.audit1.freeze()
        self.audit2.freeze()
        self.prediction.activate()
        self.encoder.activate()

    def audit_only(self):
        self.audit1.activate()
        self.audit2.activate()
        self.prediction.freeze()
        self.encoder.freeze()

    def finetune_only(self):
        self.audit1.freeze()
        self.audit2.freeze()
        self.prediction.activate()
        self.encoder.freeze()

    def predict_params(self):
        return list(self.prediction.parameters()) + list(
            self.encoder.parameters())

    def audit_params(self):
        return list(self.audit1.parameters()) + list(self.audit2.parameters())

    def finetune_params(self):
        return self.prediction.parameters()
Esempio n. 3
0
File: dcfr.py Progetto: windxrz/DCFR
class DCFR(FairRepr):
    def __init__(self, config, n_fair):
        super(DCFR, self).__init__("DCFR", config)

        self.encoder = MLP([config["xdim"]] + config["encoder"] +
                           [config["zdim"]], "relu")
        self.prediction = MLP(
            [config["zdim"]] + config["prediction"] + [config["ydim"]],
            "relu",
        )

        self.audit = MLP(
            [config["zdim"] + n_fair] + config["audit"] + [config["sdim"]],
            "relu",
        )

    def forward_y(self, x):
        z = self.forward_z(x)
        y = self.prediction(z)
        y = torch.sigmoid(y)
        return y

    def forward_s(self, x, f):
        z = self.forward_z(x)
        s = self.audit(torch.cat([z, f], dim=1))
        s = torch.sigmoid(s)
        return s

    def forward_z(self, x):
        z = torch.nn.functional.relu(self.encoder(x))
        return z

    def forward(self, x):
        self.forward_y(x)

    def loss_prediction(self, x, y, w):
        y_pred = self.forward_y(x)
        loss = weighted_cross_entropy(w, y, y_pred)
        return loss

    def loss_audit(self, x, s, f, w):
        s_pred = self.forward_s(x, f)
        loss = weighted_mse(w, s, s_pred)
        return loss

    def weight_audit(self, df_old, s, f):
        df = df_old.copy()
        df["w"] = 0.0

        if self.task == "DP":
            df["n_f"] = df.shape[0]
        else:
            res = df.groupby(f).count()["w"].reset_index().rename(
                columns={"w": "n_f"})
            df = df.merge(res, on=f, how="left")

        res = (df.groupby(f + [s]).count()["w"].reset_index().rename(
            columns={"w": "n_s_f"}))
        df = df.merge(res, on=f + [s], how="left")

        df["w"] = 1 - df["n_s_f"] / df["n_f"]

        res = torch.from_numpy(df["w"].values).view(-1, 1)
        res = res / res.sum()
        return res

    def predict_only(self):
        self.audit.freeze()
        self.prediction.activate()
        self.encoder.activate()

    def audit_only(self):
        self.audit.activate()
        self.prediction.freeze()
        self.encoder.freeze()

    def finetune_only(self):
        self.audit.freeze()
        self.prediction.activate()
        self.encoder.freeze()

    def predict_params(self):
        return list(self.prediction.parameters()) + list(
            self.encoder.parameters())

    def audit_params(self):
        return self.audit.parameters()

    def finetune_params(self):
        return self.prediction.parameters()
Esempio n. 4
0
class Unfair(FairRepr):
    def __init__(self, config):
        super(Unfair, self).__init__("UNFAIR", config)

        self.encoder = MLP([config["xdim"]] + config["encoder"] +
                           [config["zdim"]], "relu")
        self.prediction = MLP(
            [config["zdim"]] + config["prediction"] + [config["ydim"]],
            "relu",
        )

    def forward_y(self, x):
        z = self.forward_z(x)
        y = self.prediction(z)
        y = torch.sigmoid(y)
        return y

    def forward_s(self, x, f):
        return x.sum(dim=1) / x.sum(dim=1)

    def forward_z(self, x):
        z = torch.nn.functional.relu(self.encoder(x))
        return z

    def forward(self, x):
        self.forward_y(x)

    def loss_prediction(self, x, y, w):
        y_pred = self.forward_y(x)
        loss = weighted_cross_entropy(w, y, y_pred)
        return loss

    def loss_reconstruction(self, x, w):
        x_pred = self.forward_x(x)
        loss = weighted_mse(w, x, x_pred)
        return loss

    def loss_audit(self, x, s, f, w):
        return torch.sum(x - x)

    def predict_only(self):
        self.prediction.activate()
        self.encoder.activate()

    def audit_only(self):
        pass

    def finetune_only(self):
        self.prediction.activate()
        self.encoder.freeze()

    def predict_params(self):
        return list(self.prediction.parameters()) + list(
            self.encoder.parameters())

    def audit_params(self):
        return None

    def finetune_params(self):
        return list(self.prediction.parameters()) + list(
            self.encoder.parameters())
Esempio n. 5
0
class LAFTR(FairRepr):
    def __init__(self, config):
        super(LAFTR, self).__init__("LAFTR", config)
        self.encoder = MLP(
            [config["xdim"]] + config["encoder"] + [config["zdim"]], "relu"
        )
        self.prediction = MLP(
            [config["zdim"]] + config["prediction"] + [config["ydim"]],
            "relu",
        )
        self.audit = MLP([config["zdim"]] + config["audit"] + [config["sdim"]], "relu")

    def forward_y(self, x):
        z = self.forward_z(x)
        y = self.prediction(z)
        y = torch.sigmoid(y)
        return y

    def forward_s(self, x, f):
        z = self.forward_z(x)
        s = self.audit(z)
        s = torch.sigmoid(s)
        return s

    def forward_z(self, x):
        z = torch.nn.functional.relu(self.encoder(x))
        return z

    def forward(self, x):
        self.forward_y(x)

    def loss_prediction(self, x, y, w):
        y_pred = self.forward_y(x)
        loss = weighted_cross_entropy(w, y, y_pred)
        return loss

    def loss_audit(self, x, s, f, w):
        s_pred = self.forward_s(x, f)
        loss = weighted_mse(w, s, s_pred)
        return loss

    def weight_audit(self, df_old, s, f):
        df = df_old.copy()
        df["w"] = 0.0
        if self.task == "DP":
            amount = df.loc[df[s] == 1].shape[0]
            df.loc[df[s] == 1, "w"] = 1.0 / amount / 2
            df.loc[df[s] == 0, "w"] = 1.0 / (df.shape[0] - amount) / 2
        elif self.task == "EO":
            for ss in range(2):
                for y in range(2):
                    amount = df.loc[(df[s] == ss) & (df["result"] == y)].shape[0]
                    df.loc[(df[s] == ss) & (df["result"] == y), "w"] = 1.0 / amount / 4
        elif self.task == "CF":
            res = (
                df.groupby(f + [s])
                .count()["w"]
                .reset_index()
                .rename(columns={"w": "n_s_f"})
            )
            df = df.merge(res, on=f + [s], how="left")
            df["w"] = 1.0 / df["n_s_f"]

        res = torch.from_numpy(df["w"].values).view(-1, 1)
        res = res / res.sum()
        return res

    def predict_only(self):
        self.audit.freeze()
        self.prediction.activate()
        self.encoder.activate()

    def audit_only(self):
        self.audit.activate()
        self.prediction.freeze()
        self.encoder.freeze()

    def finetune_only(self):
        self.audit.freeze()
        self.prediction.activate()
        self.encoder.freeze()

    def predict_params(self):
        return list(self.prediction.parameters()) + list(self.encoder.parameters())

    def audit_params(self):
        return self.audit.parameters()

    def finetune_params(self):
        return self.prediction.parameters()