def test_retrieval_of_classifier_training_jobs_from_exploration_attributes(
            self):
        """Test the get_classifier_training_job method."""

        exp_id = u'1'
        next_scheduled_check_time = datetime.datetime.utcnow()
        state_name = u'टेक्स्ट'
        algorithm_id = feconf.INTERACTION_CLASSIFIER_MAPPING['TextInput'][
            'algorithm_id']
        algorithm_version = feconf.INTERACTION_CLASSIFIER_MAPPING['TextInput'][
            'algorithm_version']
        job_id = self._create_classifier_training_job(
            algorithm_id, 'TextInput', exp_id, 1, next_scheduled_check_time,
            [], state_name, feconf.TRAINING_JOB_STATUS_NEW, {},
            algorithm_version)
        classifier_models.StateTrainingJobsMappingModel.create(
            exp_id, 1, state_name, {algorithm_id: job_id})

        classifier_training_job = (
            classifier_services.get_classifier_training_job(
                exp_id, 1, state_name, algorithm_id))
        self.assertIsNotNone(classifier_training_job)
        self.assertEqual(classifier_training_job.exp_id, exp_id)
        self.assertEqual(classifier_training_job.exp_version, 1)
        self.assertEqual(classifier_training_job.state_name, state_name)
        self.assertEqual(classifier_training_job.job_id, job_id)

        # Test that method returns a list with None as elements when job does
        # not exist.
        false_state_name = 'false_name'
        classifier_training_job = (
            classifier_services.get_classifier_training_job(
                exp_id, 1, false_state_name, algorithm_id))
        self.assertIsNone(classifier_training_job)
    def test_reverted_exploration_maintains_classifier_model_mapping(
            self) -> None:
        """Test if the classifier model mapping is maintained when an
        exploration is reverted.
        """

        state_name = 'Home'
        exploration = exp_fetchers.get_exploration_by_id(self.exp_id)
        interaction_id = exploration.states[state_name].interaction.id
        algorithm_id = feconf.INTERACTION_CLASSIFIER_MAPPING[interaction_id][
            'algorithm_id']

        # Make changes to the exploration.
        change_list = [
            exp_domain.ExplorationChange({
                'cmd': exp_domain.CMD_EDIT_EXPLORATION_PROPERTY,
                'property_name': 'title',
                'new_value': 'A new title'
            })
        ]
        with self.swap(feconf, 'ENABLE_ML_CLASSIFIERS', True):
            exp_services.update_exploration(  # type: ignore[no-untyped-call]
                feconf.SYSTEM_COMMITTER_ID, self.exp_id, change_list, '')

        current_exploration = exp_fetchers.get_exploration_by_id(self.exp_id)
        # Store the job before reverting the exploration.
        old_job = classifier_services.get_classifier_training_job(
            self.exp_id, current_exploration.version, state_name, algorithm_id)
        # Ruling out the possibility of None for mypy type checking.
        assert old_job is not None
        old_job_id = old_job.job_id
        # Revert the exploration.
        with self.swap(feconf, 'ENABLE_ML_CLASSIFIERS', True):
            exp_services.revert_exploration(  # type: ignore[no-untyped-call]
                feconf.SYSTEM_COMMITTER_ID, self.exp_id,
                current_exploration.version, current_exploration.version - 1)
        # Verify if classifier model mapping is maintained using the job ID.
        reverted_exploration = exp_fetchers.get_exploration_by_id(self.exp_id)
        self.assertEqual(reverted_exploration.version,
                         current_exploration.version + 1)
        new_job = classifier_services.get_classifier_training_job(
            self.exp_id, reverted_exploration.version, state_name,
            algorithm_id)
        # Ruling out the possibility of None for mypy type checking.
        assert new_job is not None
        new_job_id = new_job.job_id
        self.assertEqual(old_job_id, new_job_id)
Exemple #3
0
 def test_trained_classifier_handler(self):
     # Normal end-to-end test.
     self.post_blob('/ml/trainedclassifierhandler',
                    self.payload_proto.SerializeToString(),
                    expected_status_int=200)
     classifier_training_job = (
         classifier_services.get_classifier_training_job(
             self.exp_id, self.exploration.version, 'Home',
             self.algorithm_id))
     self.assertIsNotNone(classifier_training_job)
     classifier_data = (
         self._get_classifier_data_from_classifier_training_job(
             classifier_training_job))
     self.assertEqual(json.loads(classifier_data.model_json),
                      self.classifier_data)
     self.assertEqual(classifier_training_job.status,
                      feconf.TRAINING_JOB_STATUS_COMPLETE)
Exemple #4
0
    def test_get_trained_classifier_handler(self):
        self.post_blob('/ml/trainedclassifierhandler',
                       self.payload_proto.SerializeToString(),
                       expected_status_int=200)
        classifier_training_job = (
            classifier_services.get_classifier_training_job(
                self.exp_id, self.exploration.version, 'Home',
                self.algorithm_id))

        params = {
            'exploration_id': self.exp_id,
            'exploration_version': self.exploration.version,
            'state_name': 'Home',
        }
        response = self.get_json('/ml/trainedclassifierhandler',
                                 params=params,
                                 expected_status_int=200)
        self.assertEqual(response['gcs_filename'],
                         classifier_training_job.classifier_data_filename)
Exemple #5
0
    def setUp(self):
        super(TrainedClassifierHandlerTests, self).setUp()

        self.exp_id = 'exp_id1'
        self.title = 'Testing Classifier storing'
        self.category = 'Test'
        yaml_path = os.path.join(feconf.TESTS_DATA_DIR,
                                 'string_classifier_test.yaml')
        with python_utils.open_file(yaml_path, 'r') as yaml_file:
            self.yaml_content = yaml_file.read()
        self.signup(self.CURRICULUM_ADMIN_EMAIL,
                    self.CURRICULUM_ADMIN_USERNAME)
        self.signup('*****@*****.**', 'mod')

        assets_list = []
        with self.swap(feconf, 'ENABLE_ML_CLASSIFIERS', True):
            exp_services.save_new_exploration_from_yaml_and_assets(
                feconf.SYSTEM_COMMITTER_ID, self.yaml_content, self.exp_id,
                assets_list)
        self.exploration = exp_fetchers.get_exploration_by_id(self.exp_id)
        self.algorithm_id = feconf.INTERACTION_CLASSIFIER_MAPPING[
            self.exploration.states['Home'].interaction.id]['algorithm_id']
        self.algorithm_version = feconf.INTERACTION_CLASSIFIER_MAPPING[
            self.exploration.states['Home'].interaction.
            id]['algorithm_version']

        self.classifier_data = {
            '_alpha': 0.1,
            '_beta': 0.001,
            '_prediction_threshold': 0.5,
            '_training_iterations': 25,
            '_prediction_iterations': 5,
            '_num_labels': 10,
            '_num_docs': 12,
            '_num_words': 20,
            '_label_to_id': {
                'text': 1
            },
            '_word_to_id': {
                'hello': 2
            },
            '_w_dp': [],
            '_b_dl': [],
            '_l_dp': [],
            '_c_dl': [],
            '_c_lw': [],
            '_c_l': [],
        }
        classifier_training_job = (
            classifier_services.get_classifier_training_job(
                self.exp_id, self.exploration.version, 'Home',
                self.algorithm_id))
        self.assertIsNotNone(classifier_training_job)
        self.job_id = classifier_training_job.job_id

        # TODO(pranavsid98): Replace the three commands below with
        # mark_training_job_pending after Giritheja's PR gets merged.
        classifier_training_job_model = (
            classifier_models.ClassifierTrainingJobModel.get(self.job_id,
                                                             strict=False))
        classifier_training_job_model.status = (
            feconf.TRAINING_JOB_STATUS_PENDING)
        classifier_training_job_model.update_timestamps()
        classifier_training_job_model.put()

        self.job_result = (training_job_response_payload_pb2.
                           TrainingJobResponsePayload.JobResult())
        self.job_result.job_id = self.job_id

        classifier_frozen_model = (
            text_classifier_pb2.TextClassifierFrozenModel())
        classifier_frozen_model.model_json = json.dumps(self.classifier_data)

        self.job_result.text_classifier.CopyFrom(classifier_frozen_model)

        self.payload_proto = (
            training_job_response_payload_pb2.TrainingJobResponsePayload())
        self.payload_proto.job_result.CopyFrom(self.job_result)
        self.payload_proto.vm_id = feconf.DEFAULT_VM_ID
        self.secret = feconf.DEFAULT_VM_SHARED_SECRET
        self.payload_proto.signature = classifier_services.generate_signature(
            python_utils.convert_to_bytes(self.secret),
            python_utils.convert_to_bytes(
                self.payload_proto.job_result.SerializeToString()),
            self.payload_proto.vm_id)

        self.payload_for_fetching_next_job_request = {
            'vm_id': feconf.DEFAULT_VM_ID,
            'message': json.dumps({})
        }

        self.payload_for_fetching_next_job_request['signature'] = (
            classifier_services.generate_signature(
                python_utils.convert_to_bytes(self.secret),
                python_utils.convert_to_bytes(
                    self.payload_for_fetching_next_job_request['message']),
                self.payload_for_fetching_next_job_request['vm_id']))