Skip to content

Commit

Permalink
Merge branch 'main' into kartikch/add-genai-metrics
Browse files Browse the repository at this point in the history
  • Loading branch information
kartikc727 authored Jan 26, 2024
2 parents 00ff86c + f1cf49c commit 1d63392
Show file tree
Hide file tree
Showing 9 changed files with 144 additions and 116 deletions.
Original file line number Diff line number Diff line change
@@ -1,13 +1,7 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.

import {
DatasetTaskType,
IDataset,
IModelExplanationData
} from "@responsible-ai/core-ui";
import JSZip from "jszip";
import fetch from "node-fetch";
import { DatasetTaskType, IDataset } from "@responsible-ai/core-ui";

export const squadGenai: IDataset = {
categorical_features: [],
Expand Down Expand Up @@ -62,53 +56,4 @@ export const squadGenai: IDataset = {
target_column: undefined,
task_type: DatasetTaskType.GenerativeText,
true_y: undefined
};

async function getModelExplanationDataFromZip(
url: string,
jsonFileName: string
): Promise<IModelExplanationData> {
// Fetch the zip file from the URL
const response = await fetch(url);

// Check if the request was successful
if (!response.ok) {
throw new Error(`Error fetching zip file: ${response.statusText}`);
}

// Get the zip file as ArrayBuffer
const zipFileData = await response.arrayBuffer();

// Load the zip file using JSZip
const zip = await JSZip.loadAsync(zipFileData);

// Find the JSON file in the zip
const jsonFile = zip.file(jsonFileName);

if (!jsonFile) {
throw new Error(`JSON file not found: ${jsonFileName}`);
}

// Extract and parse the JSON content
const jsonData = JSON.parse(await jsonFile.async("text"));
return jsonData as IModelExplanationData;
}

export async function getSquadModelExplanationData(): Promise<
Omit<IModelExplanationData, "method" | "predictedY" | "probabilityY">
> {
// download large json file from blob storage
const zipUrl =
"https://publictestdatasets.blob.core.windows.net/data/appTestData.zip";
const jsonFileName = "squadData.json"; // Replace with the name of the JSON file inside the zip

return getModelExplanationDataFromZip(zipUrl, jsonFileName)
.then((modelExplanationData) => {
return modelExplanationData;
})
.catch((error) => {
console.error("Error:", error);
}) as Promise<
Omit<IModelExplanationData, "method" | "predictedY" | "probabilityY">
>;
}
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.

import { Stack, Text } from "@fluentui/react";
import { IVisionListItem } from "@responsible-ai/core-ui";
import { localization } from "@responsible-ai/localization";
import React from "react";

import { stackTokens } from "./FlyoutObjectDetectionUtils";

interface IDetectionDetailsProps {
item: IVisionListItem; // replace with actual type
correctDetections: string;
incorrectDetections: string;
}
export class DetectionDetails extends React.Component<IDetectionDetailsProps> {
public render(): React.ReactNode {
return (
<Stack
tokens={stackTokens.large}
horizontalAlign="start"
verticalAlign="start"
>
<Stack
horizontal
tokens={stackTokens.medium}
horizontalAlign="center"
verticalAlign="center"
/>
<Stack.Item>
<Text variant="large">
{localization.InterpretVision.Dashboard.indexLabel}
{this.props.item?.index}
</Text>
</Stack.Item>
<Stack.Item>
<Text variant="large">
{localization.InterpretVision.Dashboard.correctDetections}
{this.props.correctDetections}
</Text>
</Stack.Item>
<Stack.Item>
<Text variant="large">
{localization.InterpretVision.Dashboard.incorrectDetections}
{this.props.incorrectDetections}
</Text>
</Stack.Item>
</Stack>
);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import {
IComboBox,
IComboBoxOption,
Image,
Label,
List,
Panel,
PanelType,
Expand All @@ -24,6 +25,7 @@ import * as FlyoutStyles from "../utils/FlyoutUtils";
import { getObjectDetectionImageAltText } from "../utils/getAltTextUtils";
import { getJoinedLabelString } from "../utils/labelUtils";

import { DetectionDetails } from "./DetectionDetails";
import {
flyoutStyles,
explanationImage,
Expand Down Expand Up @@ -55,7 +57,8 @@ export class FlyoutObjectDetection extends React.Component<
const selectableObjectIndexes =
FlyoutStyles.generateSelectableObjectDetectionIndexes(
localization.InterpretVision.Dashboard.prefix,
item
item,
this.props.dataset.class_names
);
this.setState({ item, metadata, selectableObjectIndexes });
}
Expand All @@ -73,7 +76,8 @@ export class FlyoutObjectDetection extends React.Component<
const selectableObjectIndexes =
FlyoutStyles.generateSelectableObjectDetectionIndexes(
localization.InterpretVision.Dashboard.prefix,
item
item,
this.props.dataset.class_names
);
this.setState({
item: this.props.item,
Expand Down Expand Up @@ -122,42 +126,11 @@ export class FlyoutObjectDetection extends React.Component<
verticalAlign="center"
>
<Stack.Item>
<Stack
tokens={FlyoutODUtils.stackTokens.large}
horizontalAlign="start"
verticalAlign="start"
>
<Stack
horizontal
tokens={FlyoutODUtils.stackTokens.medium}
horizontalAlign="center"
verticalAlign="center"
/>
<Stack.Item>
<Text variant="large">
{localization.InterpretVision.Dashboard.indexLabel}
{item?.index}
</Text>
</Stack.Item>
<Stack.Item>
<Text variant="large">
{
localization.InterpretVision.Dashboard
.correctDetections
}
{correctDetections}
</Text>
</Stack.Item>
<Stack.Item>
<Text variant="large">
{
localization.InterpretVision.Dashboard
.incorrectDetections
}
{incorrectDetections}
</Text>
</Stack.Item>
</Stack>
<DetectionDetails
item={item}
correctDetections={correctDetections}
incorrectDetections={incorrectDetections}
/>
</Stack.Item>
</Stack>
</Stack.Item>
Expand All @@ -173,13 +146,17 @@ export class FlyoutObjectDetection extends React.Component<
{localization.InterpretVision.Dashboard.panelInformation}
</Text>
</Stack.Item>
<Stack.Item className={classNames.featureListContainer}>
<Stack.Item
className={classNames.featureListContainer}
tabIndex={0}
>
<List
items={this.state.metadata}
onRenderCell={FlyoutStyles.onRenderCell}
/>
</Stack.Item>
</Stack>
<FlyoutODUtils.ColorLegend />
<Stack>
<Stack.Item className={classNames.imageContainer}>
<Stack.Item id="canvasToolsDiv">
Expand All @@ -200,17 +177,27 @@ export class FlyoutObjectDetection extends React.Component<
</Text>
</Stack.Item>
<Stack>
{
<ComboBox
id={localization.InterpretVision.Dashboard.objectSelect}
label={localization.InterpretVision.Dashboard.chooseObject}
onChange={this.selectODChoiceFromDropdown}
selectedKey={this.state.odSelectedKey}
options={this.state.selectableObjectIndexes}
className={"classNames.dropdown"}
styles={FluentUIStyles.smallDropdownStyle}
/>
}
<Label
id={
localization.InterpretVision.Dashboard.objectSelectionLabel
}
>
{localization.InterpretVision.Dashboard.chooseObject}
</Label>
<ComboBox
id={localization.InterpretVision.Dashboard.objectSelect}
onChange={this.selectODChoiceFromDropdown}
selectedKey={this.state.odSelectedKey}
options={this.state.selectableObjectIndexes}
className="classNames.dropdown"
styles={FluentUIStyles.smallDropdownStyle}
ariaLabel={
localization.InterpretVision.Dashboard.chooseObject
}
aria-labelledby={
localization.InterpretVision.Dashboard.objectSelectionLabel
}
/>
<Stack>
{!this.props.loadingExplanation[item.index][
+this.state.odSelectedKey.slice(
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.

import { IComboBoxOption, getTheme } from "@fluentui/react";
import { IComboBoxOption, getTheme, Stack, Text } from "@fluentui/react";
import { IDataset, IVisionListItem } from "@responsible-ai/core-ui";
import { localization } from "@responsible-ai/localization";
import React from "react";
import { CanvasTools } from "vott-ct";
import { Editor } from "vott-ct/lib/js/CanvasTools/CanvasTools.Editor";
import { RegionData } from "vott-ct/lib/js/CanvasTools/Core/RegionData";
Expand Down Expand Up @@ -31,6 +32,42 @@ export const stackTokens = {
large: { childrenGap: "l2" },
medium: { childrenGap: "l1" }
};

const theme = getTheme();

export class ColorLegend extends React.Component {
public render(): React.ReactNode {
return (
<Stack horizontal tokens={stackTokens.large}>
<Stack horizontal tokens={stackTokens.medium}>
<Text variant="medium">
{localization.InterpretVision.Dashboard.trueY}
</Text>
<div
style={{
backgroundColor: theme.palette.green,
height: 20,
width: 20
}}
/>
</Stack>
<Stack horizontal tokens={stackTokens.medium}>
<Text variant="medium">
{localization.InterpretVision.Dashboard.predictedY}
</Text>
<div
style={{
backgroundColor: theme.palette.magenta,
height: 20,
width: 20
}}
/>
</Stack>
</Stack>
);
}
}

export const ExcessLabelLen =
localization.InterpretVision.Dashboard.prefix.length;

Expand Down Expand Up @@ -109,8 +146,6 @@ export function drawBoundingBoxes(
return;
}

const theme = getTheme();

// Ensuring object detection labels are populated
if (
!dataset.object_detection_predicted_y ||
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,13 +34,14 @@ export function onRenderCell(

export function generateSelectableObjectDetectionIndexes(
prefix: string,
item: IVisionListItem | undefined
item: IVisionListItem | undefined,
classNames: string[] | undefined
): IComboBoxOption[] {
const temp = item?.odPredictedY;
const selectableObjectIndexes: IComboBoxOption[] = [];
if (temp) {
if (temp && classNames) {
for (let i = 0; i < Object.values(temp).length; i++) {
const className = item?.predictedY[i];
const className = classNames[temp[i][0] - 1];
selectableObjectIndexes.push({
key: prefix + String(i),
text: String(i) + String(": ") + className
Expand Down
1 change: 1 addition & 0 deletions libs/localization/src/lib/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -1477,6 +1477,7 @@
"multiselect": "Multiselect",
"notdefined": "object scenario not defined",
"objectSelect": "Object Selection",
"objectSelectionLabel": "objectSelectLabel",
"pageSize": "Page size: ",
"panelTitle": "Selected instance",
"panelExplanation": "Explanation",
Expand Down
5 changes: 4 additions & 1 deletion raiwidgets/raiwidgets/dashboard.py
Original file line number Diff line number Diff line change
Expand Up @@ -61,14 +61,17 @@ def __init__(self, *,
port,
locale,
no_inline_dashboard=False,
is_private_link=False,
**kwargs):
"""Initialize the dashboard."""

if model_data is None or type is None:
raise ValueError("Required parameters not provided")

try:
self._service = FlaskHelper(ip=public_ip, port=port)
self._service = FlaskHelper(ip=public_ip,
port=port,
is_private_link=is_private_link)
except Exception as e:
self._service = None
raise e
Expand Down
7 changes: 6 additions & 1 deletion raiwidgets/raiwidgets/responsibleai_dashboard.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,10 +29,14 @@ class ResponsibleAIDashboard(Dashboard):
:param cohort_list:
List of cohorts defined by the user for the dashboard.
:type cohort_list: List[Cohort]
:param is_private_link: If the dashboard environment is
a private link AML workspace.
:type is_private_link: bool
"""
def __init__(self, analysis: RAIInsights,
public_ip=None, port=None, locale=None,
cohort_list=None, **kwargs):
cohort_list=None, is_private_link=False,
**kwargs):
self.input = ResponsibleAIDashboardInput(
analysis, cohort_list=cohort_list)

Expand All @@ -43,6 +47,7 @@ def __init__(self, analysis: RAIInsights,
port=port,
locale=locale,
no_inline_dashboard=True,
is_private_link=is_private_link,
**kwargs)

def predict():
Expand Down
Loading

0 comments on commit 1d63392

Please sign in to comment.