예제 #1
0
 def __init__(self, object, scene, alpha_file, PO_file):
     self.known_attributes = {}
     (self.SP, self.CP) = self.do_PO(PO_file)
     self.all_props = self.SP + self.CP
     self.cat = None
     self.type = None
     self.g = 5
     self.a = 1
     self.alpha = self.read_alpha(alpha_file)
     # self.beta['color']['red'] = .5
     # self.beta['color']['orange'] = .5
     # self.beta['color']['yellow'] = .5
     # self.beta['color']['green'] = .5
     # self.beta['color']['blue'] = .5
     # self.beta['color']['purple'] = .5
     # self.beta['color']['black'] = .5
     # self.beta['color']['white'] = .5
     # self.beta['color']['grey'] = .5
     # self.beta['color']['material'] = .5
     # The size algorithm
     self.calc_size = SizeAlgorithm.SizeAlgorithm()
     # The knowledge base
     self.protoKB = Prototypes()
     self.protohash = self.protoKB.protohash
     self.refer(object, scene)
예제 #2
0
class Refer:
    def __init__(self, object, scene, alpha_file, PO_file):
        self.known_attributes = {}
        (self.SP, self.CP) = self.do_PO(PO_file)
        self.all_props = self.SP + self.CP
        self.cat = None
        self.type = None
        self.g = 5
        self.a = 1
        self.alpha = self.read_alpha(alpha_file)
        # self.beta['color']['red'] = .5
        # self.beta['color']['orange'] = .5
        # self.beta['color']['yellow'] = .5
        # self.beta['color']['green'] = .5
        # self.beta['color']['blue'] = .5
        # self.beta['color']['purple'] = .5
        # self.beta['color']['black'] = .5
        # self.beta['color']['white'] = .5
        # self.beta['color']['grey'] = .5
        # self.beta['color']['material'] = .5
        # The size algorithm
        self.calc_size = SizeAlgorithm.SizeAlgorithm()
        # The knowledge base
        self.protoKB = Prototypes()
        self.protohash = self.protoKB.protohash
        self.refer(object, scene)

    def do_PO(self, PO_file):
        SP_atts = ["colour", "size", "location", "orientation"]
        CP_atts = ["shape", "material", "texture", "sheen", "form", "opacity"]
        SP = []
        CP = []
        if PO_file == None:
            SP = SP_atts
            CP = CP_atts
        else:
            SP = []
            po = open(PO_file, "r").read()
            po = po.strip()
            po = po.split()
            for att in po:
                if att in SP_atts:
                    SP += [att]
                elif att in CP_atts:
                    CP += [att]
        return (SP, CP)

    def refer(self, obj, scene):
        # -- Parallel process 1 --
        r = []
        # Get the object category from visual similarity (type, with typical properties)
        self.cat = self.protoKB.find_category(obj)
        if self.cat != None:
            self.type = self.cat["type"]
        else:
            # Unsure of object:
            # Placeholder lemma that would correspond to the surface form, e.g., "thing"
            self.type = "thing"
        # -- Parallel process 2 --
        r = self.analyze_simple_properties(obj, scene, r)
        r = self.analyze_complex_properties(obj, scene, r)
        r += [("type", self.type)]
        self.generate_reference(r)

    def analyze_simple_properties(self, obj, scene, r):
        # -- Parallel process 1.1 --
        # Attributes are represented as multi-featured vectors.
        # For color, this includes luminances and intensities
        att = "colour"
        val = self.do_attribute(obj, scene, att)
        self.known_attributes[att] = val
        for i_att in self.protoKB.interconnections:
            # All at once....in parallel....But it's only material in testing, so it shouldn't matter
            if att in self.protoKB.interconnections[i_att]:
                i_val = self.do_attribute(obj, scene, i_att)
                self.known_attributes[i_att] = i_val
                try:
                    if att in self.protoKB.implies[(i_att, i_val)]:
                        if (
                            val in self.protoKB.implies[(i_att, i_val)][att]
                            or val == self.protoKB.implies[(i_att, i_val)][att]
                        ):
                            if self.cat != None and self.type in self.protohash:
                                try:
                                    if i_val in self.protohash[self.type][i_att]:
                                        beta = self.protohash[self.type][i_att][i_val]
                                    else:
                                        # Equivalent to saying it is ATYPICAL, so mention it.
                                        beta = 0.0
                                except KeyError:
                                    # No stored typical things for this attribute; treat it as unremarkable.
                                    beta = 1.0
                                go = self.throw_dice(self.alpha[i_att], self.val_salience(att, val), len(r), beta)
                            if go:
                                r += self.lemma(i_val, i_att)
                except KeyError:
                    continue
        if self.cat != None and self.type in self.protohash:
            try:
                if val in self.protohash[self.type][att]:
                    beta = self.protohash[self.type][att][val]
                else:
                    # Equivalent to saying it is ATYPICAL, so mention it.
                    beta = 0.0
            except KeyError:
                # No stored typical things for this attribute; treat it as unremarkable.
                beta = 1.0
            go = self.throw_dice(self.alpha[att], self.val_salience(att, val), len(r), beta)
            if go:
                r += self.lemma(val, att)
        else:
            go = self.throw_dice(self.alpha[att], self.val_salience(att, val), len(r))
        if go:
            r += self.lemma(val, "colour")
        # -- Parallel process 1.2 --
        # Compare with other items in the scene for relative properties.
        # Here the relative attribute is size.
        # It is an open question how to compare the stored typical
        # size of the object to the sizes of items of the same type
        # in the scene; for now I make the simplifying assumption that
        # contrast set is the main factor.
        for att in ("size", "location", "orientation"):
            # Different classifier/algorithm for each kind of attribute
            # The size algorithm is from my size work.
            val = self.do_attribute(obj, scene, att)
            self.known_attributes[att] = val
            len_r = len(r)
            # Equivalent to a parallel process.
            if att == "size":
                len_r = 0
            if val == "Unknown":
                continue
            if self.cat != None:
                go = self.throw_dice(self.alpha[att], self.val_salience(att, val), len_r)
            else:
                go = self.throw_dice(self.alpha[att], self.val_salience(att, val), len_r)
            if go:
                r += self.lemma(val, att)
        return r

    def analyze_complex_properties(self, obj, scene, r):
        # Should this be parallel or incremental?
        # Probably associated to lemmas incrementally, so we will run this
        # incrementally.
        # So we need a preference order for this, don't we?  Yes.
        # print "CP is", self.CP
        for att in self.CP:
            if att not in self.known_attributes:
                # Different classifier/algorithm for each kind of attribute
                val = self.do_attribute(obj, scene, att)
                self.known_attributes[att] = val
            else:
                val = self.known_attributes[att]
            if val == "Unknown":
                continue
            val_salience = 0
            if self.cat != None and self.type in self.protohash:
                # sys.stderr.write("Considering " + att + "\n")
                try:
                    if val in self.protohash[self.type][att]:
                        beta = self.protohash[self.type][att][val]
                    else:
                        # Equivalent to saying it is ATYPICAL, so mention it.
                        beta = 0.0
                except KeyError:
                    # No stored typical things for this attribute; treat it as unremarkable.
                    beta = 1.0
                # sys.stderr.write("Input beta is " + str(beta) + "\n")
                go = self.throw_dice(self.alpha[att], self.val_salience(att, val), len(r), beta)
                # print go
                # if not go:
                #        sys.stderr.write("no go\n")
            else:
                go = self.throw_dice(self.alpha[att], self.val_salience(att, val), len(r))
            if go:
                r += self.lemma(val, att)
        # Each object is examined incrementally,
        # following the original idea in Pechmann [1989]
        for d in scene:
            d_obj = Fixate(scene[d])
            d_cat = self.protoKB.find_category(d_obj)
            if d_obj["pos"] == obj["pos"]:
                continue
            if self.cat:
                if d_cat["type"] == self.type:
                    for att in self.all_props:
                        # print att
                        d_val = self.do_attribute(d_obj, scene, att)
                        t_val = self.known_attributes[att]
                        if t_val == "Unknown":
                            continue
                        if d_val != t_val:
                            l = self.lemma(t_val, att, d_val)
                            # Don't add something we've already said.
                            if l[0] in r:
                                continue
                            go = self.throw_dice(1, 1, len(r))
                            if go:
                                # print "After comparison, adding", l
                                r += l
        return r

    def do_attribute(self, obj, scene, att):
        # Just gold-standard for now:  We know the "real"
        # value of the attribute.
        # if att == "color":
        #    c = obj['colors']
        #    l = obj['luminances']
        #    i = obj['intensities']
        #    val = self.__get_color__(c, l, i)
        if att == "size":
            h = obj["height"]
            w = obj["width"]
            val = self.__get_size__(h, w, obj, scene)
        else:
            val = obj[att]
        return val

    def lemma(self, val, att, d_val=None):
        if att == "size":
            val = Size(val).lemma
        return [(att, val)]

    def throw_dice(self, alpha, val_salience, penalty, beta=1.0):
        weight_function = 1
        if penalty == 0:
            gamma = 1
        else:
            gamma = 1 / (float(penalty) * self.g)
        alpha *= self.a
        delta = val_salience
        # Playing with this
        # gamma = self.num_mods[penalty]
        # sys.stderr.write("alpha is " + str(alpha) + " delta is " + str(delta) + " gamma is " + str(gamma) + " beta is " + str(beta) + "\n")
        weight_function = alpha * delta * gamma + ((1 - beta) * (1 - (alpha * delta)))
        # print "alpha:", alpha, "beta:", beta
        # print weight_function
        # sys.stderr.write("weight function is " +  str(weight_function) + "\n")
        # What if I just do this?
        # weight_function = alpha
        n = random.random()
        # print "weight_function is", weight_function, "n is", n
        if n < weight_function:
            return True
        else:
            return False

    def val_salience(self, att, val):
        if att == "colour":
            return 1
        elif att == "size":
            return 1
        return 1

    def read_alpha(self, f):
        alpha_hash = {}
        o = open(f, "r")
        r_o = o.readlines()
        o.close()
        tmp_hash = {}
        for feat in r_o:
            feat = feat.strip()
            feat = feat.split(":")
            att = feat[0]
            weight = float(feat[1])
            tmp_hash[att] = weight
        for att in self.all_props:
            if att not in tmp_hash:
                tmp_hash[att] = 0.0
        alpha_hash = tmp_hash
        return alpha_hash

    def __get_distractors__(self, obj, scene):
        d = []
        for object_id in scene:
            d_object = scene[object_id]
            # Should actually be a function of the similarity....
            if d_object["pos"] != obj["pos"]:
                if d_object["type"] == self.type:
                    d += [d_object]
        return d

    def __average__(self, distractors):
        h = 0.0
        w = 0.0
        for o in distractors:
            h += float(o["height"])
            w += float(o["width"])
        h /= float(len(distractors))
        w /= float(len(distractors))
        return (h, w)

    def __get_size__(self, h, w, obj, scene):
        height = float(h)
        width = float(w)
        distractors = self.__get_distractors__(obj, scene)
        # print distractors
        # Ariely (1990?), Oliva and Torralba
        if distractors != []:
            (contrast_height, contrast_width) = self.__average__(distractors)
            (mod, pol) = self.calc_size.size_mod(width, height, contrast_width, contrast_height)
            size = (mod, pol)
            return size
        return None

    def generate_reference(self, ref):
        for (att, val) in ref:
            if val == "Unknown":
                continue
            if val:
                print val,
        print "\t\t+",
        said = {}
        for (att, val) in ref:
            if val == None or val == "":
                continue
            if (att, val) in said:
                continue
            print "tg" + ":" + att + ":" + val,
            said[(att, val)] = {}
        print ""
예제 #3
0
import sys